summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/client_priv.h4
-rw-r--r--client/completion_hash.cc2
-rw-r--r--client/mysql.cc118
-rw-r--r--client/mysql_plugin.c17
-rw-r--r--client/mysql_upgrade.c12
-rw-r--r--client/mysqlbinlog.cc239
-rw-r--r--client/mysqlcheck.c27
-rw-r--r--client/mysqldump.c337
-rw-r--r--client/mysqlimport.c2
-rw-r--r--client/mysqlshow.c6
-rw-r--r--client/mysqlslap.c20
-rw-r--r--client/mysqltest.cc262
12 files changed, 650 insertions, 396 deletions
diff --git a/client/client_priv.h b/client/client_priv.h
index ffc564a90d1..5e764cc33fd 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -1,6 +1,6 @@
/*
Copyright (c) 2001, 2012, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -61,6 +61,7 @@ enum options_client
OPT_USE_THREADS,
OPT_IMPORT_USE_THREADS,
OPT_MYSQL_NUMBER_OF_QUERY,
+ OPT_IGNORE_DATABASE,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
OPT_TZ_UTC, OPT_CREATE_SLAP_SCHEMA,
OPT_MYSQLDUMP_SLAVE_APPLY,
@@ -99,6 +100,7 @@ enum options_client
OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_SSL_CRL, OPT_SSL_CRLPATH,
OPT_IGNORE_DATA,
+ OPT_PRINT_ROW_COUNT, OPT_PRINT_ROW_EVENT_POSITIONS,
OPT_CHECK_IF_UPGRADE_NEEDED,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/completion_hash.cc b/client/completion_hash.cc
index 30c0dc6260b..e5d3f485810 100644
--- a/client/completion_hash.cc
+++ b/client/completion_hash.cc
@@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize)
ht->initialized = 0;
return FAILURE;
}
- init_alloc_root(&ht->mem_root, 8192, 0, MYF(0));
+ init_alloc_root(&ht->mem_root, "completion_hash", 8192, 0, MYF(0));
ht->pHashFunction = hashpjw;
ht->nTableSize = nSize;
ht->initialized = 1;
diff --git a/client/mysql.cc b/client/mysql.cc
index 382c216f772..558b54e3909 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2018, Oracle and/or its affiliates.
- Copyright (c) 2009, 2018, MariaDB Corporation
+ Copyright (c) 2009, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
#include <signal.h>
#include <violite.h>
#include <my_sys.h>
-
+#include <source_revision.h>
#if defined(USE_LIBEDIT_INTERFACE) && defined(HAVE_LOCALE_H)
#include <locale.h>
#endif
@@ -94,6 +94,9 @@ extern "C" {
# include <editline/readline.h>
# else
# include <readline.h>
+# if !defined(USE_LIBEDIT_INTERFACE)
+# include <history.h>
+# endif
# endif
#define HAVE_READLINE
#endif
@@ -1047,30 +1050,14 @@ static const char *embedded_server_groups[]=
{ "server", "embedded", "mysql_SERVER", "mariadb_SERVER", 0 };
#ifdef HAVE_READLINE
-/*
- HIST_ENTRY is defined for libedit, but not for the real readline
- Need to redefine it for real readline to find it
-*/
-#if !defined(HAVE_HIST_ENTRY)
-typedef struct _hist_entry {
- const char *line;
- const char *data;
-} HIST_ENTRY;
-#endif
-
-extern "C" int add_history(const char *command); /* From readline directory */
-extern "C" int read_history(const char *command);
-extern "C" int write_history(const char *command);
-extern "C" HIST_ENTRY *history_get(int num);
-extern "C" int history_length;
static int not_in_history(const char *line);
-static void initialize_readline (char *name);
+static void initialize_readline ();
static void fix_history(String *final_command);
#endif
static COMMANDS *find_command(char *name);
static COMMANDS *find_command(char cmd_name);
-static bool add_line(String &, char *, ulong, char *, bool *, bool);
+static bool add_line(String &, char *, size_t line_length, char *, bool *, bool);
static void remove_cntrl(String &buffer);
static void print_table_data(MYSQL_RES *result);
static void print_table_data_html(MYSQL_RES *result);
@@ -1078,9 +1065,7 @@ static void print_table_data_xml(MYSQL_RES *result);
static void print_tab_data(MYSQL_RES *result);
static void print_table_data_vertically(MYSQL_RES *result);
static void print_warnings(void);
-static ulong start_timer(void);
-static void end_timer(ulong start_time,char *buff);
-static void mysql_end_timer(ulong start_time,char *buff);
+static void end_timer(ulonglong start_time, char *buff);
static void nice_time(double sec,char *buff,bool part_second);
extern "C" sig_handler mysql_end(int sig) __attribute__ ((noreturn));
extern "C" sig_handler handle_sigint(int sig);
@@ -1210,7 +1195,7 @@ int main(int argc,char *argv[])
sf_leaking_memory= 0;
glob_buffer.realloc(512);
completion_hash_init(&ht, 128);
- init_alloc_root(&hash_mem_root, 16384, 0, MYF(0));
+ init_alloc_root(&hash_mem_root, "hash", 16384, 0, MYF(0));
if (sql_connect(current_host,current_db,current_user,opt_password,
opt_silent))
{
@@ -1247,7 +1232,7 @@ int main(int argc,char *argv[])
}
#ifdef HAVE_READLINE
- initialize_readline((char*) my_progname);
+ initialize_readline();
if (!status.batch && !quick && !opt_html && !opt_xml)
{
/* read-history from file, default ~/.mysql_history*/
@@ -1717,19 +1702,18 @@ static struct my_option my_long_options[] =
static void usage(int version)
{
+#ifdef HAVE_READLINE
#if defined(USE_LIBEDIT_INTERFACE)
const char* readline= "";
#else
const char* readline= "readline";
#endif
-
-#ifdef HAVE_READLINE
printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n",
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
readline, rl_library_version);
#else
- printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER,
- MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+ printf("%s Ver %s Distrib %s, for %s (%s), source revision %s\n", my_progname, VER,
+ MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION);
#endif
if (version)
@@ -1994,7 +1978,7 @@ static int read_and_execute(bool interactive)
ulong line_number=0;
bool ml_comment= 0;
COMMANDS *com;
- ulong line_length= 0;
+ size_t line_length= 0;
status.exit_status=1;
real_binary_mode= !interactive && opt_binary_mode;
@@ -2288,7 +2272,7 @@ static COMMANDS *find_command(char *name)
}
-static bool add_line(String &buffer, char *line, ulong line_length,
+static bool add_line(String &buffer, char *line, size_t line_length,
char *in_string, bool *ml_comment, bool truncated)
{
uchar inchar;
@@ -2350,7 +2334,7 @@ static bool add_line(String &buffer, char *line, ulong line_length,
'\0' within the data and not to end parsing if found.
*/
if (!(inchar = (uchar) *++pos) && (!real_binary_mode || !*in_string))
- break; // readline adds one '\'
+ break; // readline adds one '\'
if (*in_string || inchar == 'N') // \N is short for NULL
{ // Don't allow commands in string
*out++='\\';
@@ -2685,10 +2669,11 @@ static int fake_magic_space(const char *, int)
}
-static void initialize_readline (char *name)
+static void initialize_readline ()
{
/* Allow conditional parsing of the ~/.inputrc file. */
- rl_readline_name = name;
+ rl_readline_name= (char *) "mysql";
+ rl_terminal_name= getenv("TERM");
/* Tell the completer that we want a crack first. */
#if defined(USE_NEW_READLINE_INTERFACE)
@@ -3003,12 +2988,12 @@ static void get_current_db()
The different commands
***************************************************************************/
-int mysql_real_query_for_lazy(const char *buf, int length)
+int mysql_real_query_for_lazy(const char *buf, size_t length)
{
for (uint retry=0;; retry++)
{
int error;
- if (!mysql_real_query(&mysql,buf,length))
+ if (!mysql_real_query(&mysql,buf,(ulong)length))
return 0;
error= put_error(&mysql);
if (mysql_errno(&mysql) != CR_SERVER_GONE_ERROR || retry > 1 ||
@@ -3227,9 +3212,10 @@ static int
com_go(String *buffer,char *line __attribute__((unused)))
{
char buff[200]; /* about 110 chars used so far */
- char time_buff[52+3+1]; /* time max + space & parens + NUL */
+ char time_buff[53+3+1]; /* time max + space & parens + NUL */
MYSQL_RES *result;
- ulong timer, warnings= 0;
+ ulonglong timer;
+ ulong warnings= 0;
uint error= 0;
int err= 0;
@@ -3268,7 +3254,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
return 0;
}
- timer=start_timer();
+ timer= microsecond_interval_timer();
executing_query= 1;
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
report_progress_end();
@@ -3307,7 +3293,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
}
if (verbose >= 3 || !opt_silent)
- mysql_end_timer(timer,time_buff);
+ end_timer(timer, time_buff);
else
time_buff[0]= '\0';
@@ -3578,10 +3564,10 @@ is_binary_field(MYSQL_FIELD *field)
/* Print binary value as hex literal (0x ...) */
static void
-print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send)
+print_as_hex(FILE *output_file, const char *str, size_t len, size_t total_bytes_to_send)
{
const char *ptr= str, *end= ptr+len;
- ulong i;
+ size_t i;
fprintf(output_file, "0x");
for(; ptr < end; ptr++)
fprintf(output_file, "%02X", *((uchar*)ptr));
@@ -3631,11 +3617,11 @@ print_table_data(MYSQL_RES *result)
(void) tee_fputs("|", PAGER);
for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
{
- uint name_length= (uint) strlen(field->name);
- uint numcells= charset_info->cset->numcells(charset_info,
+ size_t name_length= (uint) strlen(field->name);
+ size_t numcells= charset_info->cset->numcells(charset_info,
field->name,
field->name + name_length);
- uint display_length= field->max_length + name_length - numcells;
+ size_t display_length= field->max_length + name_length - numcells;
tee_fprintf(PAGER, " %-*s |",(int) MY_MIN(display_length,
MAX_COLUMN_LENGTH),
field->name);
@@ -3656,7 +3642,6 @@ print_table_data(MYSQL_RES *result)
const char *buffer;
uint data_length;
uint field_max_length;
- uint visible_length;
uint extra_padding;
if (off)
@@ -3684,7 +3669,7 @@ print_table_data(MYSQL_RES *result)
We need to find how much screen real-estate we will occupy to know how
many extra padding-characters we should send with the printing function.
*/
- visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
+ size_t visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
extra_padding= (uint) (data_length - visible_length);
if (opt_binhex && is_binary_field(field))
@@ -4219,8 +4204,7 @@ com_edit(String *buffer,char *line __attribute__((unused)))
const char *editor;
MY_STAT stat_arg;
- if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY,
- MYF(MY_WME))) < 0)
+ if ((fd= create_temp_file(filename,NullS,"sql", 0, MYF(MY_WME))) < 0)
goto err;
if (buffer->is_empty() && !old_buffer.is_empty())
(void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(),
@@ -5107,31 +5091,11 @@ void tee_putc(int c, FILE *file)
putc(c, OUTFILE);
}
-#if defined(__WIN__)
-#include <time.h>
-#else
-#include <sys/times.h>
-#ifdef _SC_CLK_TCK // For mit-pthreads
-#undef CLOCKS_PER_SEC
-#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
-#endif
-#endif
-
-static ulong start_timer(void)
-{
-#if defined(__WIN__)
- return clock();
-#else
- struct tms tms_tmp;
- return times(&tms_tmp);
-#endif
-}
-
/**
Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
- len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds") -> 52
+ len("4294967296 days, 23 hours, 59 minutes, 60.000 seconds") -> 53
*/
static void nice_time(double sec,char *buff,bool part_second)
{
@@ -5158,24 +5122,20 @@ static void nice_time(double sec,char *buff,bool part_second)
buff=strmov(buff," min ");
}
if (part_second)
- sprintf(buff,"%.2f sec",sec);
+ sprintf(buff,"%.3f sec",sec);
else
sprintf(buff,"%d sec",(int) sec);
}
-static void end_timer(ulong start_time,char *buff)
+static void end_timer(ulonglong start_time, char *buff)
{
- nice_time((double) (start_timer() - start_time) /
- CLOCKS_PER_SEC,buff,1);
-}
+ double sec;
-
-static void mysql_end_timer(ulong start_time,char *buff)
-{
buff[0]=' ';
buff[1]='(';
- end_timer(start_time,buff+2);
+ sec= (microsecond_interval_timer() - start_time) / (double) (1000 * 1000);
+ nice_time(sec, buff + 2, 1);
strmov(strend(buff),")");
}
diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c
index 35852188fac..bfe394ae758 100644
--- a/client/mysql_plugin.c
+++ b/client/mysql_plugin.c
@@ -161,8 +161,7 @@ static int make_tempfile(char *filename, const char *ext)
{
int fd= 0;
- if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY,
- MYF(MY_WME))) < 0)
+ if ((fd= create_temp_file(filename, NullS, ext, 0, MYF(MY_WME))) < 0)
{
fprintf(stderr, "ERROR: Cannot generate temporary file. Error code: %d.\n",
fd);
@@ -264,7 +263,7 @@ static char *convert_path(const char *argument)
/* Convert / to \\ to make Windows paths */
char *winfilename= my_strdup(argument, MYF(MY_FAE));
char *pos, *end;
- int length= strlen(argument);
+ size_t length= strlen(argument);
for (pos= winfilename, end= pos+length ; pos < end ; pos++)
{
@@ -368,6 +367,12 @@ static int get_default_values()
}
/* Now open the file and read the defaults we want. */
file= fopen(defaults_file, "r");
+ if (file == NULL)
+ {
+ fprintf(stderr, "ERROR: failed to open file %s: %s.\n", defaults_file,
+ strerror(errno));
+ goto exit;
+ }
while (fgets(line, FN_REFLEN, file) != NULL)
{
char *value= 0;
@@ -730,11 +735,11 @@ static int check_options(int argc, char **argv, char *operation)
/* Form prefix strings for the options. */
const char *basedir_prefix = "--basedir=";
- int basedir_len= strlen(basedir_prefix);
+ size_t basedir_len= strlen(basedir_prefix);
const char *datadir_prefix = "--datadir=";
- int datadir_len= strlen(datadir_prefix);
+ size_t datadir_len= strlen(datadir_prefix);
const char *plugin_dir_prefix = "--plugin_dir=";
- int plugin_dir_len= strlen(plugin_dir_prefix);
+ size_t plugin_dir_len= strlen(plugin_dir_prefix);
strcpy(plugin_name, "");
for (i = 0; i < argc && num_found < 5; i++)
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 8c186b521c1..1cc1edd9e9e 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -596,8 +596,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
DBUG_PRINT("enter", ("query: %s", query));
if ((fd= create_temp_file(query_file_path,
opt_tmpdir[0] ? opt_tmpdir : NULL,
- "sql", O_CREAT | O_SHARE | O_RDWR,
- MYF(MY_WME))) < 0)
+ "sql", O_SHARE, MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults");
/*
@@ -1108,8 +1107,9 @@ static int install_used_engines(void)
{
char buf[512];
DYNAMIC_STRING ds_result;
- const char *query = "SELECT DISTINCT LOWER(engine) FROM information_schema.tables"
- " WHERE table_comment LIKE 'Unknown storage engine%'";
+ const char *query = "SELECT DISTINCT LOWER(engine) AS c1 FROM information_schema.tables"
+ " WHERE table_comment LIKE 'Unknown storage engine%'"
+ " ORDER BY c1";
if (opt_systables_only || !from_before_10_1())
{
@@ -1327,7 +1327,7 @@ int main(int argc, char **argv)
load_defaults_or_exit("my", load_default_groups, &argc, &argv);
defaults_argv= argv; /* Must be freed by 'free_defaults' */
-#if __WIN__
+#if defined(__WIN__)
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
{
@@ -1359,7 +1359,7 @@ int main(int argc, char **argv)
cnf_file_path= strmov(defaults_file, "--defaults-file=");
{
int fd= create_temp_file(cnf_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL,
- "mysql_upgrade-", O_CREAT | O_WRONLY, MYF(MY_FAE));
+ "mysql_upgrade-", 0, MYF(MY_FAE));
if (fd < 0)
die(NULL);
my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE));
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 4e28876cdf6..1fa16015f4a 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -32,7 +32,10 @@
#define MYSQL_CLIENT
#undef MYSQL_SERVER
#define TABLE TABLE_CLIENT
+/* This hack is here to avoid adding COMPRESSED data types to libmariadb. */
+#define MYSQL_TYPE_TIME2 MYSQL_TYPE_TIME2,MYSQL_TYPE_BLOB_COMPRESSED=140,MYSQL_TYPE_VARCHAR_COMPRESSED=141
#include "client_priv.h"
+#undef MYSQL_TYPE_TIME2
#include <my_time.h>
#include <sslopt-vars.h>
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
@@ -87,7 +90,8 @@ static char *result_file_name= 0;
static const char *output_prefix= "";
#ifndef DBUG_OFF
-static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
+static const char *default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace";
+const char *current_dbug_option= default_dbug_option;
#endif
static const char *load_groups[]=
{ "mysqlbinlog", "client", "client-server", "client-mariadb", 0 };
@@ -107,6 +111,8 @@ static char *opt_base64_output_mode_str= NullS;
static char* database= 0;
static char* table= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
+static my_bool print_row_count= 0, print_row_event_positions= 0;
+static my_bool print_row_count_used= 0, print_row_event_positions_used= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool force_if_open_opt= 1;
static my_bool opt_raw_mode= 0, opt_stop_never= 0;
@@ -222,13 +228,15 @@ void keep_annotate_event(Annotate_rows_log_event* event)
annotate_event= event;
}
-void print_annotate_event(PRINT_EVENT_INFO *print_event_info)
+bool print_annotate_event(PRINT_EVENT_INFO *print_event_info)
{
+ bool error= 0;
if (annotate_event)
{
annotate_event->print(result_file, print_event_info);
free_annotate_event();
}
+ return error;
}
static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *, const char*);
@@ -431,7 +439,7 @@ File Load_log_processor::prepare_new_file_for_old_format(Load_log_event *le,
return -1;
}
- le->set_fname_outside_temp_buf(filename,len+(uint) strlen(tail));
+ le->set_fname_outside_temp_buf(filename,len+strlen(tail));
return file;
}
@@ -529,7 +537,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
uint file_id,
Create_file_log_event *ce)
{
- uint full_len= target_dir_name_len + blen + 9 + 9 + 1;
+ size_t full_len= target_dir_name_len + blen + 9 + 9 + 1;
Exit_status retval= OK_CONTINUE;
char *fname, *ptr;
File file;
@@ -575,7 +583,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname,
}
if (ce)
- ce->set_fname_outside_temp_buf(fname, (uint) strlen(fname));
+ ce->set_fname_outside_temp_buf(fname, strlen(fname));
if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP)))
{
@@ -792,7 +800,7 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev)
static void
print_skip_replication_statement(PRINT_EVENT_INFO *pinfo, const Log_event *ev)
{
- int cur_val;
+ bool cur_val;
cur_val= (ev->flags & LOG_EVENT_SKIP_REPLICATION_F) != 0;
if (cur_val == pinfo->skip_replication)
@@ -844,13 +852,15 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file,
DBUG_ENTER("write_event_header_and_base64");
/* Write header and base64 output to cache */
- ev->print_header(head, print_event_info, FALSE);
+ if (ev->print_header(head, print_event_info, FALSE))
+ DBUG_RETURN(ERROR_STOP);
DBUG_ASSERT(print_event_info->base64_output_mode == BASE64_OUTPUT_ALWAYS);
- ev->print_base64(body, print_event_info,
- print_event_info->base64_output_mode !=
- BASE64_OUTPUT_DECODE_ROWS);
+ if (ev->print_base64(body, print_event_info,
+ print_event_info->base64_output_mode !=
+ BASE64_OUTPUT_DECODE_ROWS))
+ DBUG_RETURN(ERROR_STOP);
/* Read data from cache and write to result file */
if (copy_event_cache_to_file_and_reinit(head, result_file) ||
@@ -872,27 +882,21 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
passed --short-form, because --short-form disables printing
row events.
*/
+
if (!print_event_info->printed_fd_event && !short_form &&
- opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
+ opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
+ opt_base64_output_mode != BASE64_OUTPUT_NEVER)
{
const char* type_str= ev->get_type_str();
- if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
- error("--base64-output=never specified, but binlog contains a "
- "%s event which must be printed in base64.",
- type_str);
- else
- error("malformed binlog: it does not contain any "
- "Format_description_log_event. I now found a %s event, which "
+ error("malformed binlog: it does not contain any "
+ "Format_description_log_event. Found a %s event, which "
"is not safe to process without a "
"Format_description_log_event.",
type_str);
return 1;
}
- ev->print(result_file, print_event_info);
- return
- print_event_info->head_cache.error == -1 ||
- print_event_info->body_cache.error == -1 ||
- print_event_info->tail_cache.error == -1;
+
+ return ev->print(result_file, print_event_info);
}
@@ -902,6 +906,8 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
Table_map_log_event *ignored_map=
print_event_info->m_table_map_ignored.get_table(table_id);
bool skip_event= (ignored_map != NULL);
+ char ll_buff[21];
+ bool result= 0;
if (opt_flashback)
{
@@ -978,19 +984,18 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
return 0;
if (!opt_flashback)
- return print_base64(print_event_info, ev);
+ result= print_base64(print_event_info, ev);
else
{
if (is_stmt_end)
{
- bool res= false;
Log_event *e= NULL;
// Print the row_event from the last one to the first one
for (uint i= events_in_stmt.elements; i > 0; --i)
{
e= *(dynamic_element(&events_in_stmt, i - 1, Log_event**));
- res= res || print_base64(print_event_info, e);
+ result= result || print_base64(print_event_info, e);
}
// Copy all output into the Log_event
ev->output_buf.copy(e->output_buf);
@@ -1001,12 +1006,17 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
delete e;
}
reset_dynamic(&events_in_stmt);
-
- return res;
}
}
- return 0;
+ if (is_stmt_end && !result)
+ {
+ if (print_event_info->print_row_count)
+ fprintf(result_file, "# Number of rows: %s\n",
+ llstr(print_event_info->row_events, ll_buff));
+ print_event_info->row_events= 0;
+ }
+ return result;
}
@@ -1037,7 +1047,6 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
Log_event_type ev_type= ev->get_type_code();
my_bool destroy_evt= TRUE;
DBUG_ENTER("process_event");
- print_event_info->short_form= short_form;
Exit_status retval= OK_CONTINUE;
IO_CACHE *const head= &print_event_info->head_cache;
@@ -1083,7 +1092,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
retval= OK_STOP;
goto end;
}
- if (!short_form && !opt_flashback)
+ if (print_row_event_positions)
fprintf(result_file, "# at %s\n",llstr(pos,ll_buff));
if (!opt_hexdump)
@@ -1124,7 +1133,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
{
print_skip_replication_statement(print_event_info, ev);
- ev->print(result_file, print_event_info);
+ if (ev->print(result_file, print_event_info))
+ goto err;
}
if (head->error == -1)
goto err;
@@ -1159,8 +1169,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
{
print_skip_replication_statement(print_event_info, ev);
- ce->print(result_file, print_event_info, TRUE);
- if (head->error == -1)
+ if (ce->print(result_file, print_event_info, TRUE))
goto err;
}
// If this binlog is not 3.23 ; why this test??
@@ -1183,8 +1192,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
the subsequent call load_processor.process fails, because the
output of Append_block_log_event::print is only a comment.
*/
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if ((retval= load_processor.process((Append_block_log_event*) ev)) !=
OK_CONTINUE)
@@ -1193,8 +1201,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case EXEC_LOAD_EVENT:
{
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
Execute_load_log_event *exv= (Execute_load_log_event*)ev;
Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
@@ -1205,15 +1212,16 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (ce)
{
+ bool error;
/*
We must not convert earlier, since the file is used by
my_open() in Load_log_processor::append().
*/
convert_path_to_forward_slashes((char*) ce->fname);
- ce->print(result_file, print_event_info, TRUE);
+ error= ce->print(result_file, print_event_info, TRUE);
my_free((void*)ce->fname);
delete ce;
- if (head->error == -1)
+ if (error)
goto err;
}
else
@@ -1224,10 +1232,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case FORMAT_DESCRIPTION_EVENT:
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
+ destroy_evt= 0;
print_event_info->common_header_len=
glob_description_event->common_header_len;
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if (!remote_opt)
{
@@ -1257,8 +1265,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
break;
case BEGIN_LOAD_QUERY_EVENT:
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) !=
OK_CONTINUE)
@@ -1276,11 +1283,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
{
convert_path_to_forward_slashes(fname);
print_skip_replication_statement(print_event_info, ev);
- exlq->print(result_file, print_event_info, fname);
- if (head->error == -1)
+ if (exlq->print(result_file, print_event_info, fname))
{
- if (fname)
- my_free(fname);
+ my_free(fname);
goto err;
}
}
@@ -1288,9 +1293,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
warning("Ignoring Execute_load_query since there is no "
"Begin_load_query event for file_id: %u", exlq->file_id);
}
-
- if (fname)
- my_free(fname);
+ my_free(fname);
break;
}
case ANNOTATE_ROWS_EVENT:
@@ -1436,7 +1439,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print the kept Annotate event (if there is any).
print_annotate_event() also deletes the kept Annotate event.
*/
- print_annotate_event(print_event_info);
+ if (print_annotate_event(print_event_info))
+ goto err;
size_t len_to= 0;
const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to);
@@ -1466,10 +1470,18 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
{
Rows_log_event *e= (Rows_log_event*) ev;
bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F);
+ if (!print_event_info->found_row_event)
+ {
+ print_event_info->found_row_event= 1;
+ print_event_info->row_events= 0;
+ }
if (print_row_event(print_event_info, ev, e->get_table_id(),
e->get_flags(Rows_log_event::STMT_END_F)))
goto err;
- if (opt_flashback && !is_stmt_end)
+ DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end));
+ if (is_stmt_end)
+ print_event_info->found_row_event= 0;
+ else if (opt_flashback)
destroy_evt= FALSE;
break;
}
@@ -1482,7 +1494,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
if (print_row_event(print_event_info, ev, e->get_table_id(),
e->get_flags(Old_rows_log_event::STMT_END_F)))
goto err;
- if (opt_flashback && !is_stmt_end)
+ DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end));
+ if (!is_stmt_end && opt_flashback)
destroy_evt= FALSE;
break;
}
@@ -1491,8 +1504,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
/* fall through */
default:
print_skip_replication_statement(print_event_info, ev);
- ev->print(result_file, print_event_info);
- if (head->error == -1)
+ if (ev->print(result_file, print_event_info))
goto err;
}
}
@@ -1503,7 +1515,8 @@ err:
retval= ERROR_STOP;
end:
rec_count++;
-
+
+ DBUG_PRINT("info", ("end event processing"));
/*
Destroy the log_event object.
MariaDB MWL#36: mainline does this:
@@ -1547,6 +1560,7 @@ end:
if (destroy_evt) /* destroy it later if not set (ignored table map) */
delete ev;
}
+ DBUG_PRINT("exit",("return: %d", retval));
DBUG_RETURN(retval);
}
@@ -1558,14 +1572,15 @@ static struct my_option my_options[] =
{"base64-output", OPT_BASE64_OUTPUT_MODE,
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
- "statements: 'never' disables it and works only for binlogs without "
- "row-based events; 'decode-rows' decodes row events into commented SQL "
- "statements if the --verbose option is also given; 'auto' prints base64 "
- "only when necessary (i.e., for row-based events and format description "
- "events); 'always' prints base64 whenever possible. 'always' is "
- "deprecated, will be removed in a future version, and should not be used "
- "in a production system. --base64-output with no 'name' argument is "
- "equivalent to --base64-output=always and is also deprecated. If no "
+ "statements: 'never' doesn't print binlog row events and should not be "
+ "used when directing output to a MariaDB master; "
+ "'decode-rows' decodes row events into commented SQL statements if the "
+ "--verbose option is also given; "
+ "'auto' prints base64 only when necessary (i.e., for row-based events and "
+ "format description events); "
+ "'always' prints base64 whenever possible. "
+ "--base64-output with no 'name' argument is equivalent to "
+ "--base64-output=always and is also deprecated. If no "
"--base64-output[=name] option is given at all, the default is 'auto'.",
&opt_base64_output_mode_str, &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1582,8 +1597,8 @@ static struct my_option my_options[] =
&database, &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", '#', "Output debug log.", &default_dbug_option,
- &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Output debug log.", &current_dbug_option,
+ &current_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .",
&debug_check_flag, &debug_check_flag, 0,
@@ -1665,6 +1680,14 @@ static struct my_option my_options[] =
&flashback_review_tablename, &flashback_review_tablename,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"print-row-count", OPT_PRINT_ROW_COUNT,
+ "Print row counts for each row events",
+ &print_row_count, &print_row_count, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
+ 0, 0},
+ {"print-row-event-positions", OPT_PRINT_ROW_EVENT_POSITIONS,
+ "Print row event positions",
+ &print_row_event_positions, &print_row_event_positions, 0, GET_BOOL,
+ NO_ARG, 1, 0, 0, 0, 0, 0},
{"server-id", 0,
"Extract only binlog entries created by the server having the given id.",
&server_id, &server_id, 0, GET_ULONG,
@@ -1678,10 +1701,11 @@ static struct my_option my_options[] =
&shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"short-form", 's', "Just show regular queries: no extra info and no "
- "row-based events. This is for testing only, and should not be used in "
- "production systems. If you want to suppress base64-output, consider "
- "using --base64-output=never instead.",
+ {"short-form", 's', "Just show regular queries: no extra info, no "
+ "row-based events and no row counts. This is mainly for testing only, "
+ "and should not be used to feed to the MariaDB server. "
+ "If you want to just suppress base64-output, you can instead "
+ "use --base64-output=never",
&short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"socket", 'S', "The socket file to use for connection.",
@@ -1792,9 +1816,12 @@ Example: rewrite-db='from->to'.",
*/
static void error_or_warning(const char *format, va_list args, const char *msg)
{
+ if (result_file)
+ fflush(result_file);
fprintf(stderr, "%s: ", msg);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
+ fflush(stderr);
}
/**
@@ -1847,6 +1874,7 @@ static void warning(const char *format,...)
*/
static void cleanup()
{
+ DBUG_ENTER("cleanup");
my_free(pass);
my_free(database);
my_free(table);
@@ -1860,12 +1888,13 @@ static void cleanup()
delete glob_description_event;
if (mysql)
mysql_close(mysql);
+ DBUG_VOID_RETURN;
}
static void print_version()
{
- printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
+ printf("%s Ver 3.4 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
}
@@ -1916,7 +1945,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
switch (optid) {
#ifndef DBUG_OFF
case '#':
- DBUG_PUSH(argument ? argument : default_dbug_option);
+ if (!argument)
+ argument= (char*) default_dbug_option;
+ current_dbug_option= argument;
+ DBUG_PUSH(argument);
break;
#endif
#include <sslopt-case.h>
@@ -2029,6 +2061,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
binlog_filter->add_db_rewrite(key, val);
break;
}
+ case OPT_PRINT_ROW_COUNT:
+ print_row_count_used= 1;
+ break;
+ case OPT_PRINT_ROW_EVENT_POSITIONS:
+ print_row_event_positions_used= 1;
+ break;
case 'v':
if (argument == disabled_my_option)
verbose= 0;
@@ -2161,11 +2199,30 @@ static Exit_status dump_log_entries(const char* logname)
fprintf(result_file, "DELIMITER /*!*/;\n");
strmov(print_event_info.delimiter, "/*!*/;");
- print_event_info.verbose= short_form ? 0 : verbose;
+ if (short_form)
+ {
+ if (!print_row_event_positions_used)
+ print_row_event_positions= 0;
+ if (!print_row_count_used)
+ print_row_count = 0;
+ }
+ if (opt_flashback)
+ {
+ if (!print_row_event_positions_used)
+ print_row_event_positions= 0;
+ }
+ print_event_info.verbose= short_form ? 0 : verbose;
+ print_event_info.short_form= short_form;
+ print_event_info.print_row_count= print_row_count;
+ print_event_info.file= result_file;
+ fflush(result_file);
rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) :
dump_local_log_entries(&print_event_info, logname));
+ if (rc == ERROR_STOP)
+ return rc;
+
/* Set delimiter back to semicolon */
if (!opt_raw_mode && !opt_flashback)
fprintf(result_file, "DELIMITER ;\n");
@@ -2236,6 +2293,8 @@ static Exit_status check_master_version()
}
delete glob_description_event;
+ glob_description_event= NULL;
+
switch (version) {
case 3:
glob_description_event= new Format_description_log_event(1);
@@ -2254,7 +2313,6 @@ static Exit_status check_master_version()
glob_description_event= new Format_description_log_event(3);
break;
default:
- glob_description_event= NULL;
error("Could not find server version: "
"Master reported unrecognized MySQL version '%s'.", row[0]);
goto err;
@@ -2495,6 +2553,7 @@ static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info,
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
+ print_event_info->file= result_file;
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
@@ -2764,7 +2823,7 @@ static Exit_status check_header(IO_CACHE* file,
Format_description_log_event *new_description_event;
my_b_seek(file, tmp_pos); /* seek back to event's start */
if (!(new_description_event= (Format_description_log_event*)
- Log_event::read_log_event(file, 0, glob_description_event,
+ Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum)))
/* EOF can't be hit here normally, so it's a real error */
{
@@ -2798,7 +2857,7 @@ static Exit_status check_header(IO_CACHE* file,
{
Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */
- if (!(ev= Log_event::read_log_event(file, 0, glob_description_event,
+ if (!(ev= Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum)))
{
/* EOF can't be hit here normally, so it's a real error */
@@ -2864,7 +2923,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
stdin in binary mode. Errors on setting this mode result in
halting the function and printing an error message to stderr.
*/
-#if defined (__WIN__) || (_WIN64)
+#if defined (__WIN__) || defined(_WIN64)
if (_setmode(fileno(stdin), O_BINARY) == -1)
{
error("Could not set binary mode on stdin.");
@@ -2912,7 +2971,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
char llbuff[21];
my_off_t old_off = my_b_tell(file);
- Log_event* ev = Log_event::read_log_event(file, 0, glob_description_event,
+ Log_event* ev = Log_event::read_log_event(file, glob_description_event,
opt_verify_binlog_checksum);
if (!ev)
{
@@ -2991,13 +3050,6 @@ int main(int argc, char** argv)
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
opt_base64_output_mode= BASE64_OUTPUT_AUTO;
- if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
- warning("The --base64-output=always flag and the --base64-output flag "
- "(with '=MODE' omitted), are deprecated. "
- "The output generated when these flags are used cannot be "
- "parsed by mysql 5.6.0 and later. "
- "The flags will be removed in a future version. "
- "Please use --base64-output=auto instead.");
my_set_max_open_files(open_files_limit);
@@ -3110,7 +3162,7 @@ int main(int argc, char** argv)
If enable flashback, need to print the events from the end to the
beginning
*/
- if (opt_flashback)
+ if (opt_flashback && retval != ERROR_STOP)
{
for (uint i= binlog_events.elements; i > 0; --i)
{
@@ -3125,12 +3177,15 @@ int main(int argc, char** argv)
}
/* Set delimiter back to semicolon */
- if (!stop_event_string.is_empty())
- fprintf(result_file, "%s", stop_event_string.ptr());
- if (!opt_raw_mode && opt_flashback)
- fprintf(result_file, "DELIMITER ;\n");
+ if (retval != ERROR_STOP)
+ {
+ if (!stop_event_string.is_empty())
+ fprintf(result_file, "%s", stop_event_string.ptr());
+ if (!opt_raw_mode && opt_flashback)
+ fprintf(result_file, "DELIMITER ;\n");
+ }
- if (!opt_raw_mode)
+ if (retval != ERROR_STOP && !opt_raw_mode)
{
/*
Issue a ROLLBACK in case the last printed binlog was crashed and had half
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 42c4cae5621..aaf77dbb743 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -543,7 +543,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
{
int view;
char *table;
- uint table_len;
+ size_t table_len;
DBUG_ENTER("process_selected_tables");
if (use_db(db))
@@ -587,6 +587,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
my_free(table_names_comma_sep);
}
else
+ {
for (; tables > 0; tables--, table_names++)
{
table= *table_names;
@@ -596,6 +597,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
continue;
handle_request_for_tables(table, table_len, view == 1, opt_all_in_1);
}
+ }
DBUG_RETURN(0);
} /* process_selected_tables */
@@ -669,7 +671,7 @@ static int process_all_tables_in_db(char *database)
size_t tot_length = 0;
char *views, *views_end;
- uint tot_views_length = 0;
+ size_t tot_views_length = 0;
while ((row = mysql_fetch_row(res)))
{
@@ -915,16 +917,29 @@ static int handle_request_for_tables(char *tables, size_t length,
}
break;
case DO_ANALYZE:
+ if (view)
+ {
+ printf("%-50s %s\n", tables, "Can't run anaylyze on a view");
+ DBUG_RETURN(1);
+ }
DBUG_ASSERT(!view);
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
if (opt_persistent_all) end = strmov(end, " PERSISTENT FOR ALL");
break;
case DO_OPTIMIZE:
- DBUG_ASSERT(!view);
+ if (view)
+ {
+ printf("%-50s %s\n", tables, "Can't run optimize on a view");
+ DBUG_RETURN(1);
+ }
op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
break;
case DO_FIX_NAMES:
- DBUG_ASSERT(!view);
+ if (view)
+ {
+ printf("%-50s %s\n", tables, "Can't run fix names on a view");
+ DBUG_RETURN(1);
+ }
DBUG_RETURN(fix_table_storage_name(tables));
}
@@ -953,7 +968,7 @@ static int handle_request_for_tables(char *tables, size_t length,
}
if (verbose >= 3)
puts(query);
- if (mysql_real_query(sock, query, query_length))
+ if (mysql_real_query(sock, query, (ulong)query_length))
{
my_snprintf(message, sizeof(message), "when executing '%s%s... %s'",
op, tab_view, options);
@@ -965,7 +980,7 @@ static int handle_request_for_tables(char *tables, size_t length,
if (opt_flush_tables)
{
query_length= sprintf(query, "FLUSH TABLES %s", table_name);
- if (mysql_real_query(sock, query, query_length))
+ if (mysql_real_query(sock, query, (ulong)query_length))
{
DBerror(sock, query);
my_free(query);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index ecca380777f..20f8278c9c2 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation.
+ Copyright (c) 2010, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,6 +42,11 @@
/* on merge conflict, bump to a higher version again */
#define DUMP_VERSION "10.19"
+/**
+ First mysql version supporting sequences.
+*/
+#define FIRST_SEQUENCE_VERSION 100300
+
#include <my_global.h>
#include <my_sys.h>
#include <my_user.h>
@@ -84,6 +89,7 @@
#define IGNORE_NONE 0x00 /* no ignore */
#define IGNORE_DATA 0x01 /* don't dump data for this table */
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
+#define IGNORE_SEQUENCE_TABLE 0x04 /* catch the SEQUENCE*/
/* Chars needed to store LONGLONG, excluding trailing '\0'. */
#define LONGLONG_LEN 20
@@ -91,11 +97,16 @@
/* Max length GTID position that we will output. */
#define MAX_GTID_LENGTH 1024
+/* Dump sequence/tables control */
+#define DUMP_TABLE_ALL -1
+#define DUMP_TABLE_TABLE 0
+#define DUMP_TABLE_SEQUENCE 1
+
static my_bool ignore_table_data(const uchar *hash_key, size_t len);
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
static ulong find_set(TYPELIB *, const char *, size_t, char **, uint *);
-static char *alloc_query_str(ulong size);
+static char *alloc_query_str(size_t size);
static void field_escape(DYNAMIC_STRING* in, const char *from);
static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_med= 1,
@@ -132,10 +143,11 @@ static TYPELIB opt_system_types=
opt_system_type_values, NULL
};
static ulonglong opt_system= 0ULL;
-static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
+static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0,
+ select_field_names_inited= 0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*mysql=0;
-static DYNAMIC_STRING insert_pat;
+static DYNAMIC_STRING insert_pat, select_field_names;
static char *opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
@@ -187,7 +199,7 @@ wrappers, they will terminate the process if there is
an allocation failure.
*/
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
- uint init_alloc, uint alloc_increment);
+ size_t init_alloc, size_t alloc_increment);
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src);
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str);
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
@@ -228,7 +240,9 @@ TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
#define MED_ENGINES "MRG_MyISAM, MRG_ISAM, CONNECT, OQGRAPH, SPIDER, VP, FEDERATED"
-HASH ignore_table, ignore_data;
+static HASH ignore_table, ignore_data;
+
+static HASH ignore_database;
static struct my_option my_long_options[] =
{
@@ -392,6 +406,11 @@ static struct my_option my_long_options[] =
&opt_hex_blob, &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", &current_host,
&current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore-database", OPT_IGNORE_DATABASE,
+ "Do not dump the specified database. To specify more than one database to ignore, "
+ "use the directive multiple times, once for each database. Only takes effect "
+ "when used together with --all-databases|-A",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-table-data", OPT_IGNORE_DATA,
"Do not dump the specified table data. To specify more than one table "
"to ignore, use the directive multiple times, once for each table. "
@@ -931,6 +950,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_TABLES:
opt_databases=0;
break;
+ case (int) OPT_IGNORE_DATABASE:
+ if (my_hash_insert(&ignore_database, (uchar*) my_strdup(argument, MYF(0))))
+ exit(EX_EOM);
+ break;
case (int) OPT_IGNORE_DATA:
{
if (!strchr(argument, '.'))
@@ -1031,6 +1054,9 @@ static int get_options(int *argc, char ***argv)
load_defaults_or_exit("my", load_default_groups, argc, argv);
defaults_argv= *argv;
+ if (my_hash_init(&ignore_database, charset_info, 16, 0, 0,
+ (my_hash_get_key) get_table_key, my_free, 0))
+ return(EX_EOM);
if (my_hash_init(&ignore_table, charset_info, 16, 0, 0,
(my_hash_get_key) get_table_key, my_free, 0))
return(EX_EOM);
@@ -1042,7 +1068,9 @@ static int get_options(int *argc, char ***argv)
my_hash_insert(&ignore_table,
(uchar*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
my_hash_insert(&ignore_table,
- (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))))
+ (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))) ||
+ my_hash_insert(&ignore_table,
+ (uchar*) my_strdup("mysql.transaction_registry", MYF(MY_WME))))
return(EX_EOM);
if (my_hash_init(&ignore_data, charset_info, 16, 0, 0,
@@ -1189,6 +1217,13 @@ static int get_options(int *argc, char ***argv)
my_progname_short);
return(EX_USAGE);
}
+ if (ignore_database.records && !opt_alldbs)
+ {
+ fprintf(stderr,
+ "%s: --ignore-database can only be used together with --all-databases.\n",
+ my_progname_short);
+ return(EX_USAGE);
+ }
if (strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME) &&
!(charset_info= get_charset_by_csname(default_charset,
MY_CS_PRIMARY, MYF(MY_WME))))
@@ -1414,8 +1449,8 @@ get_binlog_gtid_pos(char *binlog_pos_file, char *binlog_pos_offset,
if (len_pos_file >= FN_REFLEN || len_pos_offset > LONGLONG_LEN)
return 0;
- mysql_real_escape_string(mysql, file_buf, binlog_pos_file, len_pos_file);
- mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, len_pos_offset);
+ mysql_real_escape_string(mysql, file_buf, binlog_pos_file, (ulong)len_pos_file);
+ mysql_real_escape_string(mysql, offset_buf, binlog_pos_offset, (ulong)len_pos_offset);
init_dynamic_string_checked(&query, "SELECT BINLOG_GTID_POS('", 256, 1024);
dynstr_append_checked(&query, file_buf);
dynstr_append_checked(&query, "', '");
@@ -1665,7 +1700,7 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
"SET SESSION character_set_results = '%s'",
(const char *) cs_name);
- return mysql_real_query(mysql, query_buffer, query_length);
+ return mysql_real_query(mysql, query_buffer, (ulong)query_length);
}
/**
@@ -1777,6 +1812,8 @@ static void free_resources()
my_free(opt_password);
my_free(current_host);
free_root(&glob_root, MYF(0));
+ if (my_hash_inited(&ignore_database))
+ my_hash_free(&ignore_database);
if (my_hash_inited(&ignore_table))
my_hash_free(&ignore_table);
if (my_hash_inited(&ignore_data))
@@ -1784,6 +1821,7 @@ static void free_resources()
dynstr_free(&extended_row);
dynstr_free(&dynamic_where);
dynstr_free(&insert_pat);
+ dynstr_free(&select_field_names);
if (defaults_argv)
free_defaults(defaults_argv);
mysql_library_end();
@@ -2254,7 +2292,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
{
create_stmt_ptr= (*row)[i];
create_stmt_len= lengths[i];
-#ifndef DBUG_OFF
+#ifdef DBUG_ASSERT_EXISTS
body_found= 1;
#endif
}
@@ -2617,16 +2655,25 @@ static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
static uint dump_routines_for_db(char *db)
{
char query_buff[QUERY_LENGTH];
- const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
+ const char *routine_type[]= {"FUNCTION",
+ "PROCEDURE",
+ "PACKAGE",
+ "PACKAGE BODY"};
+ const char *create_caption_xml[]= {"Create Function",
+ "Create Procedure",
+ "Create Package",
+ "Create Package Body"};
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *routine_name;
- int i;
+ uint i;
FILE *sql_file= md_result_file;
MYSQL_ROW row, routine_list_row;
char db_cl_name[MY_CS_NAME_SIZE];
int db_cl_altered= FALSE;
-
+ // before 10.3 packages are not supported
+ uint upper_bound= mysql_get_server_version(mysql) >= 100300 ?
+ array_elements(routine_type) : 2;
DBUG_ENTER("dump_routines_for_db");
DBUG_PRINT("enter", ("db: '%s'", db));
@@ -2655,8 +2702,8 @@ static uint dump_routines_for_db(char *db)
if (opt_xml)
fputs("\t<routines>\n", sql_file);
- /* 0, retrieve and dump functions, 1, procedures */
- for (i= 0; i <= 1; i++)
+ /* 0, retrieve and dump functions, 1, procedures, etc. */
+ for (i= 0; i < upper_bound; i++)
{
my_snprintf(query_buff, sizeof(query_buff),
"SHOW %s STATUS WHERE Db = '%s'",
@@ -2706,12 +2753,8 @@ static uint dump_routines_for_db(char *db)
{
if (opt_xml)
{
- if (i) /* Procedures. */
- print_xml_row(sql_file, "routine", routine_res, &row,
- "Create Procedure");
- else /* Functions. */
- print_xml_row(sql_file, "routine", routine_res, &row,
- "Create Function");
+ print_xml_row(sql_file, "routine", routine_res, &row,
+ create_caption_xml[i]);
continue;
}
if (opt_drop)
@@ -2811,9 +2854,71 @@ static inline my_bool general_log_or_slow_log_tables(const char *db,
{
return (!my_strcasecmp(charset_info, db, "mysql")) &&
(!my_strcasecmp(charset_info, table, "general_log") ||
- !my_strcasecmp(charset_info, table, "slow_log"));
+ !my_strcasecmp(charset_info, table, "slow_log") ||
+ !my_strcasecmp(charset_info, table, "transaction_registry"));
}
+/*
+ get_sequence_structure-- retrievs sequence structure, prints out corresponding
+ CREATE statement
+ ARGS
+ seq - sequence name
+ db - db name
+*/
+static void get_sequence_structure(const char *seq, const char *db)
+{
+
+ char table_buff[NAME_LEN*2+3];
+ char *result_seq;
+ FILE *sql_file= md_result_file;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+
+ DBUG_ENTER("get_sequence_structure");
+ DBUG_PRINT("enter", ("db: %s sequence: %s", db, seq));
+
+ verbose_msg("-- Retrieving sequence structure for %s...\n", seq);
+
+ result_seq= quote_name(seq, table_buff, 1);
+ // Sequences as tables share same flags
+ if (!opt_no_create_info)
+ {
+ char buff[20+FN_REFLEN];
+ my_snprintf(buff, sizeof(buff), "SHOW CREATE SEQUENCE %s", result_seq);
+ if (mysql_query_with_error_report(mysql, &result, buff))
+ {
+ DBUG_VOID_RETURN;
+ }
+
+ print_comment(sql_file, 0,
+ "\n--\n-- Sequence structure for %s\n--\n\n",
+ fix_for_comment(result_seq));
+ if (opt_drop)
+ {
+ fprintf(sql_file, "DROP SEQUENCE IF EXISTS %s;\n", result_seq);
+ check_io(sql_file);
+ }
+
+ row= mysql_fetch_row(result);
+ fprintf(sql_file, "%s;\n", row[1]);
+ mysql_free_result(result);
+
+ // Restore next not cached value from sequence
+ my_snprintf(buff, sizeof(buff), "SELECT next_not_cached_value FROM %s", result_seq);
+ if (mysql_query_with_error_report(mysql, &result, buff))
+ {
+ DBUG_VOID_RETURN;
+ }
+ row= mysql_fetch_row(result);
+ if (row[0])
+ {
+ fprintf(sql_file, "SELECT SETVAL(%s, %s, 0);\n", result_seq, row[0]);
+ }
+ // Sequences will not use inserts, so no need for REPLACE and LOCKS
+ mysql_free_result(result);
+ }
+ DBUG_VOID_RETURN;
+}
/*
get_table_structure -- retrievs database structure, prints out corresponding
CREATE statement and fills out insert_pat if the table is the type we will
@@ -2849,7 +2954,7 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
"FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "
"TABLE_SCHEMA = %s AND TABLE_NAME = %s";
FILE *sql_file= md_result_file;
- int len;
+ size_t len;
my_bool is_log_table;
MYSQL_RES *result;
MYSQL_ROW row;
@@ -2878,7 +2983,13 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
else
dynstr_set_checked(&insert_pat, "");
}
-
+ if (!select_field_names_inited)
+ {
+ select_field_names_inited= 1;
+ init_dynamic_string_checked(&select_field_names, "", 1024, 1024);
+ }
+ else
+ dynstr_set_checked(&select_field_names, "");
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
@@ -3114,6 +3225,19 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
DBUG_RETURN(0);
}
+ while ((row= mysql_fetch_row(result)))
+ {
+ if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE"))
+ complete_insert= 1;
+ if (init)
+ {
+ dynstr_append_checked(&select_field_names, ", ");
+ }
+ init=1;
+ dynstr_append_checked(&select_field_names,
+ quote_name(row[SHOW_FIELDNAME], name_buff, 0));
+ }
+ init=0;
/*
If write_data is true, then we build up insert statements for
the table's data. Note: in subsequent lines of code, this test
@@ -3141,19 +3265,8 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
}
}
- while ((row= mysql_fetch_row(result)))
- {
- if (complete_insert)
- {
- if (init)
- {
- dynstr_append_checked(&insert_pat, ", ");
- }
- init=1;
- dynstr_append_checked(&insert_pat,
- quote_name(row[SHOW_FIELDNAME], name_buff, 0));
- }
- }
+ if (complete_insert)
+ dynstr_append_checked(&insert_pat, select_field_names.str);
num_fields= mysql_num_rows(result);
mysql_free_result(result);
}
@@ -3213,6 +3326,21 @@ static uint get_table_structure(const char *table, const char *db, char *table_t
while ((row= mysql_fetch_row(result)))
{
+ if (strlen(row[SHOW_EXTRA]) && strstr(row[SHOW_EXTRA],"INVISIBLE"))
+ complete_insert= 1;
+ if (init)
+ {
+ dynstr_append_checked(&select_field_names, ", ");
+ }
+ dynstr_append_checked(&select_field_names,
+ quote_name(row[SHOW_FIELDNAME], name_buff, 0));
+ init=1;
+ }
+ init=0;
+ mysql_data_seek(result, 0);
+
+ while ((row= mysql_fetch_row(result)))
+ {
ulong *lengths= mysql_fetch_lengths(result);
if (init)
{
@@ -3728,7 +3856,7 @@ static void field_escape(DYNAMIC_STRING* in, const char *from)
-static char *alloc_query_str(ulong size)
+static char *alloc_query_str(size_t size)
{
char *query;
@@ -3763,8 +3891,10 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
char table_type[NAME_LEN];
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
int error= 0;
- ulong rownr, row_break, total_length, init_length;
+ ulong rownr, row_break;
uint num_fields;
+ size_t total_length, init_length;
+
MYSQL_RES *res;
MYSQL_FIELD *field;
MYSQL_ROW row;
@@ -3850,7 +3980,9 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
/* now build the query string */
- dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
+ dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
+ dynstr_append_checked(&query_string, select_field_names.str);
+ dynstr_append_checked(&query_string, " INTO OUTFILE '");
dynstr_append_checked(&query_string, filename);
dynstr_append_checked(&query_string, "'");
@@ -3886,7 +4018,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
order_by= 0;
}
- if (mysql_real_query(mysql, query_string.str, query_string.length))
+ if (mysql_real_query(mysql, query_string.str, (ulong)query_string.length))
{
dynstr_free(&query_string);
DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
@@ -3899,7 +4031,9 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
"\n--\n-- Dumping data for table %s\n--\n",
fix_for_comment(result_table));
- dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
+ dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ ");
+ dynstr_append_checked(&query_string, select_field_names.str);
+ dynstr_append_checked(&query_string, " FROM ");
dynstr_append_checked(&query_string, result_table);
if (where)
@@ -4172,7 +4306,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key,
if (extended_insert)
{
- ulong row_length;
+ size_t row_length;
dynstr_append_checked(&extended_row,")");
row_length= 2 + extended_row.length;
if (total_length + row_length < opt_net_buffer_length)
@@ -4250,18 +4384,36 @@ err:
} /* dump_table */
-static char *getTableName(int reset)
+static char *getTableName(int reset, int want_sequences)
{
MYSQL_ROW row;
if (!get_table_name_result)
{
- if (!(get_table_name_result= mysql_list_tables(mysql,NullS)))
- return(NULL);
+ if (mysql_get_server_version(mysql) >= FIRST_SEQUENCE_VERSION)
+ {
+ const char *query= "SHOW FULL TABLES";
+ if (mysql_query_with_error_report(mysql, 0, query))
+ return (NULL);
+
+ if (!(get_table_name_result= mysql_store_result(mysql)))
+ return (NULL);
+ }
+ else
+ {
+ if (!(get_table_name_result= mysql_list_tables(mysql,NullS)))
+ return(NULL);
+ }
}
if ((row= mysql_fetch_row(get_table_name_result)))
- return((char*) row[0]);
+ {
+ if (want_sequences != DUMP_TABLE_ALL)
+ while (row && MY_TEST(strcmp(row[1], "SEQUENCE")) == want_sequences)
+ row= mysql_fetch_row(get_table_name_result);
+ if (row)
+ return((char*) row[0]);
+ }
if (reset)
mysql_data_seek(get_table_name_result,0); /* We want to read again */
else
@@ -4758,6 +4910,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
return r;
}
+
static int dump_tablespaces_for_databases(char** databases)
{
int r;
@@ -4787,6 +4940,7 @@ static int dump_tablespaces_for_databases(char** databases)
return r;
}
+
static int dump_tablespaces(char* ts_where)
{
MYSQL_ROW row;
@@ -4817,7 +4971,8 @@ static int dump_tablespaces(char* ts_where)
" EXTRA"
" FROM INFORMATION_SCHEMA.FILES"
" WHERE FILE_TYPE = 'UNDO LOG'"
- " AND FILE_NAME IS NOT NULL",
+ " AND FILE_NAME IS NOT NULL"
+ " AND LOGFILE_GROUP_NAME IS NOT NULL",
256, 1024);
if(ts_where)
{
@@ -4832,7 +4987,7 @@ static int dump_tablespaces(char* ts_where)
}
dynstr_append_checked(&sqlbuf,
" GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
- ", ENGINE"
+ ", ENGINE, TOTAL_EXTENTS, INITIAL_SIZE"
" ORDER BY LOGFILE_GROUP_NAME");
if (mysql_query(mysql, sqlbuf.str) ||
@@ -4973,6 +5128,14 @@ static int dump_tablespaces(char* ts_where)
DBUG_RETURN(0);
}
+
+/* Return 1 if we should copy the database */
+static my_bool include_database(const char *hash_key)
+{
+ return !my_hash_search(&ignore_database, (uchar*) hash_key, strlen(hash_key));
+}
+
+
static int dump_all_databases()
{
MYSQL_ROW row;
@@ -4991,8 +5154,9 @@ static int dump_all_databases()
!my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
- if (dump_all_tables_in_db(row[0]))
- result=1;
+ if (include_database(row[0]))
+ if (dump_all_tables_in_db(row[0]))
+ result=1;
}
mysql_free_result(tableres);
if (seen_views)
@@ -5014,8 +5178,9 @@ static int dump_all_databases()
!my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
- if (dump_all_views_in_db(row[0]))
- result=1;
+ if (include_database(row[0]))
+ if (dump_all_views_in_db(row[0]))
+ result=1;
}
mysql_free_result(tableres);
}
@@ -5171,6 +5336,7 @@ static int dump_all_tables_in_db(char *database)
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
char *afterdot;
my_bool general_log_table_exists= 0, slow_log_table_exists=0;
+ my_bool transaction_registry_table_exists= 0;
int using_mysql_db= !my_strcasecmp(charset_info, database, "mysql");
DBUG_ENTER("dump_all_tables_in_db");
@@ -5186,7 +5352,7 @@ static int dump_all_tables_in_db(char *database)
{
DYNAMIC_STRING query;
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
- for (numrows= 0 ; (table= getTableName(1)) ; )
+ for (numrows= 0 ; (table= getTableName(1, DUMP_TABLE_ALL)) ; )
{
char *end= strmov(afterdot, table);
if (include_table((uchar*) hash_key,end - hash_key))
@@ -5196,7 +5362,7 @@ static int dump_all_tables_in_db(char *database)
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
}
- if (numrows && mysql_real_query(mysql, query.str, query.length-1))
+ if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1))
{
dynstr_free(&query);
DB_error(mysql, "when using LOCK TABLES");
@@ -5220,7 +5386,19 @@ static int dump_all_tables_in_db(char *database)
DBUG_RETURN(1);
}
}
- while ((table= getTableName(0)))
+
+ if (mysql_get_server_version(mysql) >= FIRST_SEQUENCE_VERSION &&
+ !opt_no_create_info)
+ {
+ // First process sequences
+ while ((table= getTableName(1, DUMP_TABLE_SEQUENCE)))
+ {
+ char *end= strmov(afterdot, table);
+ if (include_table((uchar*) hash_key, end - hash_key))
+ get_sequence_structure(table, database);
+ }
+ }
+ while ((table= getTableName(0, DUMP_TABLE_TABLE)))
{
char *end= strmov(afterdot, table);
if (include_table((uchar*) hash_key, end - hash_key))
@@ -5273,6 +5451,8 @@ static int dump_all_tables_in_db(char *database)
general_log_table_exists= 1;
else if (!my_strcasecmp(charset_info, table, "slow_log"))
slow_log_table_exists= 1;
+ else if (!my_strcasecmp(charset_info, table, "transaction_registry"))
+ transaction_registry_table_exists= 1;
}
}
}
@@ -5319,6 +5499,13 @@ static int dump_all_tables_in_db(char *database)
verbose_msg("-- Warning: get_table_structure() failed with some internal "
"error for 'slow_log' table\n");
}
+ if (transaction_registry_table_exists)
+ {
+ if (!get_table_structure((char *) "transaction_registry",
+ database, table_type, &ignore_flag) )
+ verbose_msg("-- Warning: get_table_structure() failed with some internal "
+ "error for 'transaction_registry' table\n");
+ }
}
if (flush_privileges && using_mysql_db)
{
@@ -5360,7 +5547,7 @@ static my_bool dump_all_views_in_db(char *database)
{
DYNAMIC_STRING query;
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
- for (numrows= 0 ; (table= getTableName(1)); )
+ for (numrows= 0 ; (table= getTableName(1, DUMP_TABLE_TABLE)); )
{
char *end= strmov(afterdot, table);
if (include_table((uchar*) hash_key,end - hash_key))
@@ -5370,7 +5557,7 @@ static my_bool dump_all_views_in_db(char *database)
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
}
- if (numrows && mysql_real_query(mysql, query.str, query.length-1))
+ if (numrows && mysql_real_query(mysql, query.str, (ulong)query.length-1))
DB_error(mysql, "when using LOCK TABLES");
/* We shall continue here, if --force was given */
dynstr_free(&query);
@@ -5383,7 +5570,7 @@ static my_bool dump_all_views_in_db(char *database)
else
verbose_msg("-- dump_all_views_in_db : logs flushed successfully!\n");
}
- while ((table= getTableName(0)))
+ while ((table= getTableName(0, DUMP_TABLE_TABLE)))
{
char *end= strmov(afterdot, table);
if (include_table((uchar*) hash_key, end - hash_key))
@@ -5513,7 +5700,7 @@ static int get_sys_var_lower_case_table_names()
static int dump_selected_tables(char *db, char **table_names, int tables)
{
- char table_buff[NAME_LEN*2+3];
+ char table_buff[NAME_LEN*2+3], table_type[NAME_LEN];
DYNAMIC_STRING lock_tables_query;
char **dump_tables, **pos, **end;
int lower_case_table_names;
@@ -5522,7 +5709,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
if (init_dumping(db, init_dumping_tables))
DBUG_RETURN(1);
- init_alloc_root(&glob_root, 8192, 0, MYF(0));
+ init_alloc_root(&glob_root, "glob_root", 8192, 0, MYF(0));
if (!(dump_tables= pos= (char**) alloc_root(&glob_root,
tables * sizeof(char *))))
die(EX_EOM, "alloc_root failure.");
@@ -5566,7 +5753,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
!my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME)))
{
if (mysql_real_query(mysql, lock_tables_query.str,
- lock_tables_query.length-1))
+ (ulong)lock_tables_query.length-1))
{
if (!ignore_errors)
{
@@ -5610,9 +5797,22 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DBUG_RETURN(1);
}
}
+
+ if (mysql_get_server_version(mysql) >= FIRST_SEQUENCE_VERSION)
+ {
+ /* Dump Sequence first */
+ for (pos= dump_tables; pos < end; pos++)
+ {
+ DBUG_PRINT("info",("Dumping sequence(?) %s", *pos));
+ if (check_if_ignore_table(*pos, table_type) & IGNORE_SEQUENCE_TABLE)
+ get_sequence_structure(*pos, db);
+ }
+ }
/* Dump each selected table */
for (pos= dump_tables; pos < end; pos++)
{
+ if (check_if_ignore_table(*pos, table_type) & IGNORE_SEQUENCE_TABLE)
+ continue;
DBUG_PRINT("info",("Dumping table %s", *pos));
dump_table(*pos, db, NULL, 0);
if (opt_dump_triggers &&
@@ -6153,7 +6353,7 @@ char check_if_ignore_table(const char *table_name, char *table_type)
/* Check memory for quote_for_like() */
DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
my_snprintf(buff, sizeof(buff),
- "SELECT engine FROM INFORMATION_SCHEMA.TABLES "
+ "SELECT engine, table_type FROM INFORMATION_SCHEMA.TABLES "
"WHERE table_schema = DATABASE() AND table_name = %s",
quote_for_equal(table_name, show_name_buff));
if (mysql_query_with_error_report(mysql, &res, buff))
@@ -6193,7 +6393,8 @@ char check_if_ignore_table(const char *table_name, char *table_type)
strcmp(table_type,"MEMORY"))
result= IGNORE_INSERT_DELAYED;
}
-
+ if (!strcmp(row[1],"SEQUENCE"))
+ result|= IGNORE_SEQUENCE_TABLE;
/*
If these two types, we do want to skip dumping the table
*/
@@ -6233,7 +6434,7 @@ static char *primary_key_fields(const char *table_name)
MYSQL_ROW row;
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
char show_keys_buff[15 + NAME_LEN * 2 + 3];
- uint result_length= 0;
+ size_t result_length= 0;
char *result= 0;
char buff[NAME_LEN * 2 + 3];
char *quoted_field;
@@ -6551,7 +6752,7 @@ static my_bool get_view_structure(char *table, char* db)
#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
- uint init_alloc, uint alloc_increment)
+ size_t init_alloc, size_t alloc_increment)
{
if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
@@ -6594,8 +6795,6 @@ int main(int argc, char **argv)
sf_leaking_memory=1; /* don't report memory leaks on early exits */
compatible_mode_normal_str[0]= 0;
default_charset= (char *)mysql_universal_client_charset;
- bzero((char*) &ignore_table, sizeof(ignore_table));
- bzero((char*) &ignore_data, sizeof(ignore_data));
exit_code= get_options(&argc, &argv);
if (exit_code)
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index c6b160534d8..880d3ff07cf 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -419,7 +419,7 @@ static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
dynstr_append(&query, tablename);
dynstr_append(&query, " WRITE,");
}
- if (mysql_real_query(mysql, query.str, query.length-1))
+ if (mysql_real_query(mysql, query.str, (ulong)query.length-1))
db_error(mysql); /* We shall countinue here, if --force was given */
}
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 47dc7212ca2..dfa1eac3673 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -662,7 +662,7 @@ static int
list_table_status(MYSQL *mysql,const char *db,const char *wild)
{
char query[NAME_LEN + 100];
- int len;
+ size_t len;
MYSQL_RES *result;
MYSQL_ROW row;
@@ -909,7 +909,7 @@ static void print_res_header(MYSQL_RES *result)
static void print_res_top(MYSQL_RES *result)
{
- uint i,length;
+ size_t i,length;
MYSQL_FIELD *field;
putchar('+');
@@ -917,7 +917,7 @@ static void print_res_top(MYSQL_RES *result)
while((field = mysql_fetch_field(result)))
{
if ((length= strlen(field->name)) > field->max_length)
- field->max_length=length;
+ field->max_length=(ulong)length;
else
length=field->max_length;
for (i=length+2 ; i--> 0 ; )
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 7e93068977e..19544384670 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -144,7 +144,7 @@ static unsigned long connect_flags= CLIENT_MULTI_RESULTS |
CLIENT_MULTI_STATEMENTS |
CLIENT_REMEMBER_OPTIONS;
-static int verbose, delimiter_length;
+static int verbose;
static uint commit_rate;
static uint detach_rate;
const char *num_int_cols_opt;
@@ -263,7 +263,7 @@ void option_cleanup(option_string *stmt);
void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr);
static int run_statements(MYSQL *mysql, statement *stmt);
int slap_connect(MYSQL *mysql);
-static int run_query(MYSQL *mysql, const char *query, int len);
+static int run_query(MYSQL *mysql, const char *query, size_t len);
static const char ALPHANUMERICS[]=
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
@@ -339,9 +339,6 @@ int main(int argc, char **argv)
if (auto_generate_sql)
srandom((uint)time(NULL));
- /* globals? Yes, so we only have to run strlen once */
- delimiter_length= strlen(delimiter);
-
if (argc > 2)
{
fprintf(stderr,"%s: Too many arguments\n",my_progname);
@@ -1196,9 +1193,6 @@ get_options(int *argc,char ***argv)
if (debug_check_flag)
my_end_arg= MY_CHECK_ERROR;
- if (!user)
- user= (char *)"root";
-
/*
If something is created and --no-drop is not specified, we drop the
schema.
@@ -1548,18 +1542,18 @@ get_options(int *argc,char ***argv)
}
-static int run_query(MYSQL *mysql, const char *query, int len)
+static int run_query(MYSQL *mysql, const char *query, size_t len)
{
if (opt_only_print)
{
- printf("%.*s;\n", len, query);
+ printf("%.*s;\n", (int)len, query);
return 0;
}
if (verbose >= 3)
- printf("%.*s;\n", len, query);
+ printf("%.*s;\n", (int)len, query);
- return mysql_real_query(mysql, query, len);
+ return mysql_real_query(mysql, query, (ulong)len);
}
@@ -2127,7 +2121,7 @@ parse_delimiter(const char *script, statement **stmt, char delm)
char *ptr= (char *)script;
statement **sptr= stmt;
statement *tmp;
- uint length= strlen(script);
+ size_t length= strlen(script);
uint count= 0; /* We know that there is always one */
for (tmp= *sptr= (statement *)my_malloc(sizeof(statement),
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 6d5b6ff31b6..bca35b74a64 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -71,10 +71,6 @@ static my_bool non_blocking_api_enabled= 0;
#include "../tests/nonblock-wrappers.h"
#endif
-/* Use cygwin for --exec and --system before 5.0 */
-#if MYSQL_VERSION_ID < 50000
-#define USE_CYGWIN
-#endif
#define MAX_VAR_NAME_LENGTH 256
#define MAX_COLUMNS 256
@@ -189,7 +185,7 @@ static uint opt_connect_timeout= 0;
static uint opt_wait_for_pos_timeout= 0;
static const uint default_wait_for_pos_timeout= 300;
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
-static uint delimiter_length= 1;
+static size_t delimiter_length= 1;
static char TMPDIR[FN_REFLEN];
static char global_subst_from[200];
@@ -271,8 +267,8 @@ static void free_re(void);
static char *get_string(char **to_ptr, char **from_ptr,
struct st_command *command);
static int replace(DYNAMIC_STRING *ds_str,
- const char *search_str, ulong search_len,
- const char *replace_str, ulong replace_len);
+ const char *search_str, size_t search_len,
+ const char *replace_str, size_t replace_len);
static uint opt_protocol=0;
@@ -297,11 +293,11 @@ const char *result_file_name= 0;
typedef struct
{
char *name;
- int name_len;
+ size_t name_len;
char *str_val;
- int str_val_len;
+ size_t str_val_len;
int int_val;
- int alloced_len;
+ size_t alloced_len;
bool int_dirty; /* do not update string if int is updated until first read */
bool is_int;
bool alloced;
@@ -583,7 +579,7 @@ struct st_replace_regex *glob_replace_regex= 0;
struct st_replace;
struct st_replace *glob_replace= 0;
void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
-const char *from, int len);
+const char *from);
ATTRIBUTE_NORETURN
static void cleanup_and_exit(int exit_code);
@@ -600,27 +596,25 @@ void verbose_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
void log_msg(const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
VAR* var_from_env(const char *, const char *);
-VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
- int val_len);
+VAR* var_init(VAR* v, const char *name, size_t name_len, const char *val, size_t val_len);
VAR* var_get(const char *var_name, const char** var_name_end,
my_bool raw, my_bool ignore_not_existing);
void eval_expr(VAR* v, const char *p, const char** p_end,
bool open_end=false, bool do_eval=true);
-my_bool match_delimiter(int c, const char *delim, uint length);
+my_bool match_delimiter(int c, const char *delim, size_t length);
void dump_result_to_reject_file(char *buf, int size);
void dump_warning_messages();
void do_eval(DYNAMIC_STRING *query_eval, const char *query,
const char *query_end, my_bool pass_through_escape_chars);
-void str_to_file(const char *fname, char *str, int size);
-void str_to_file2(const char *fname, char *str, int size, my_bool append);
+void str_to_file(const char *fname, char *str, size_t size);
+void str_to_file2(const char *fname, char *str, size_t size, my_bool append);
void fix_win_paths(char *val, size_t len);
const char *get_errname_from_code (uint error_code);
int multi_reg_replace(struct st_replace_regex* r,char* val);
#ifdef _WIN32
-void free_tmp_sh_file();
void free_win_path_patterns();
#endif
@@ -712,6 +706,8 @@ public:
void write(DYNAMIC_STRING* ds)
{
DBUG_ENTER("LogFile::write");
+ DBUG_PRINT("enter", ("length: %u", (uint) ds->length));
+
DBUG_ASSERT(m_file);
if (ds->length == 0)
@@ -1088,9 +1084,9 @@ static void init_connection_thd(struct st_connection *cn)
#else /* ! EMBEDDED_LIBRARY*/
#define init_connection_thd(X) do { } while(0)
-#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, q_len)
+#define do_send_query(cn,q,q_len) mysql_send_query(cn->mysql, q, (ulong)q_len)
#define do_read_query_result(cn) mysql_read_query_result(cn->mysql)
-#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, q_len)
+#define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, (ulong)q_len)
#define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt)
#define do_stmt_close(cn) mysql_stmt_close(cn->stmt)
@@ -1471,7 +1467,6 @@ void free_used_memory()
free_re();
my_free(read_command_buf);
#ifdef _WIN32
- free_tmp_sh_file();
free_win_path_patterns();
#endif
DBUG_VOID_RETURN;
@@ -1554,7 +1549,7 @@ static void make_error_message(char *buf, size_t len, const char *fmt, va_list a
fmt= "unknown error";
s+= my_vsnprintf(s, end - s, fmt, args);
- s+= my_snprintf(s, end -s, "\n", start_lineno);
+ s+= my_snprintf(s, end -s, "\n");
}
static void die(const char *fmt, ...)
@@ -2086,8 +2081,8 @@ int compare_files2(File fd1, const char* filename2)
trees when Maria is merged into them.
--global-subst should be removed.
*/
- uint global_subst_from_len= strlen(global_subst_from);
- uint global_subst_to_len= strlen(global_subst_to);
+ size_t global_subst_from_len= strlen(global_subst_from);
+ size_t global_subst_to_len= strlen(global_subst_to);
while (replace(&fd1_result,
global_subst_from, global_subst_from_len,
global_subst_to, global_subst_to_len) == 0)
@@ -2158,8 +2153,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_ENTER("dyn_string_cmp");
DBUG_PRINT("enter", ("fname: %s", fname));
- if ((fd= create_temp_file(temp_file_path, TMPDIR,
- "tmp", O_CREAT | O_SHARE | O_RDWR,
+ if ((fd= create_temp_file(temp_file_path, TMPDIR, "tmp", O_SHARE,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for ds");
@@ -2369,10 +2363,9 @@ void var_check_int(VAR *v)
}
-VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
- int val_len)
+VAR *var_init(VAR *v, const char *name, size_t name_len, const char *val, size_t val_len)
{
- int val_alloc_len;
+ size_t val_alloc_len;
VAR *tmp_var;
if (!name_len && name)
name_len = strlen(name);
@@ -2673,7 +2666,8 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
init_dynamic_string(&ds_query, 0, (end - query) + 32, 256);
do_eval(&ds_query, query, end, FALSE);
- if (mysql_real_query(mysql, ds_query.str, ds_query.length) || !(res= mysql_store_result(mysql)))
+ if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length) ||
+ !(res= mysql_store_result(mysql)))
{
handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), &ds_res);
@@ -2703,7 +2697,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
{
/* Add column to tab separated string */
char *val= row[i];
- int len= lengths[i];
+ size_t len= lengths[i];
if (glob_replace_regex)
{
@@ -2716,7 +2710,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
}
if (glob_replace)
- replace_strings_append(glob_replace, &result, val, len);
+ replace_strings_append(glob_replace, &result, val);
else
dynstr_append_mem(&result, val, len);
}
@@ -2854,7 +2848,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
die("Mismatched \"'s around query '%s'", ds_query.str);
/* Run the query */
- if (mysql_real_query(mysql, ds_query.str, ds_query.length))
+ if (mysql_real_query(mysql, ds_query.str, (ulong)ds_query.length))
{
handle_error(curr_command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), &ds_res);
@@ -3001,7 +2995,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
struct st_command command;
memset(&command, 0, sizeof(command));
command.query= (char*)p;
- command.first_word_len= len;
+ command.first_word_len= (int)len;
command.first_argument= command.query + len;
command.end= (char*)*p_end;
command.abort_on_error= 1; /* avoid uninitialized variables */
@@ -3012,11 +3006,11 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
NO_EVAL:
{
- int new_val_len = (p_end && *p_end) ?
- (int) (*p_end - p) : (int) strlen(p);
+ size_t new_val_len = (p_end && *p_end) ?
+ (size_t)(*p_end - p) : strlen(p);
if (new_val_len + 1 >= v->alloced_len)
{
- static int MIN_VAR_ALLOC= 32;
+ static size_t MIN_VAR_ALLOC= 32;
v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ?
MIN_VAR_ALLOC : new_val_len + 1;
if (!(v->str_val =
@@ -3204,33 +3198,6 @@ void do_source(struct st_command *command)
}
-#if defined _WIN32
-
-#ifdef USE_CYGWIN
-/* Variables used for temporary sh files used for emulating Unix on Windows */
-char tmp_sh_name[64], tmp_sh_cmd[70];
-#endif
-
-void init_tmp_sh_file()
-{
-#ifdef USE_CYGWIN
- /* Format a name for the tmp sh file that is unique for this process */
- my_snprintf(tmp_sh_name, sizeof(tmp_sh_name), "tmp_%d.sh", getpid());
- /* Format the command to execute in order to run the script */
- my_snprintf(tmp_sh_cmd, sizeof(tmp_sh_cmd), "sh %s", tmp_sh_name);
-#endif
-}
-
-
-void free_tmp_sh_file()
-{
-#ifdef USE_CYGWIN
- my_delete(tmp_sh_name, MYF(0));
-#endif
-}
-#endif
-
-
static void init_builtin_echo(void)
{
#ifdef _WIN32
@@ -3272,8 +3239,8 @@ static void init_builtin_echo(void)
*/
static int replace(DYNAMIC_STRING *ds_str,
- const char *search_str, ulong search_len,
- const char *replace_str, ulong replace_len)
+ const char *search_str, size_t search_len,
+ const char *replace_str, size_t replace_len)
{
DYNAMIC_STRING ds_tmp;
const char *start= strstr(ds_str->str, search_str);
@@ -3346,7 +3313,6 @@ void do_exec(struct st_command *command)
}
#ifdef _WIN32
-#ifndef USE_CYGWIN
/* Replace /dev/null with NUL */
while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0)
;
@@ -3354,7 +3320,6 @@ void do_exec(struct st_command *command)
while(replace(&ds_cmd, ">&-", 3, ">&4", 3) == 0)
;
#endif
-#endif
if (disable_result_log)
{
@@ -3512,13 +3477,7 @@ int do_modify_var(struct st_command *command,
int my_system(DYNAMIC_STRING* ds_cmd)
{
-#if defined _WIN32 && defined USE_CYGWIN
- /* Dump the command into a sh script file and execute with system */
- str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length);
- return system(tmp_sh_cmd);
-#else
return system(ds_cmd->str);
-#endif
}
@@ -3552,12 +3511,10 @@ void do_system(struct st_command *command)
do_eval(&ds_cmd, command->first_argument, command->end, !is_windows);
#ifdef _WIN32
-#ifndef USE_CYGWIN
/* Replace /dev/null with NUL */
while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0)
;
#endif
-#endif
DBUG_PRINT("info", ("running system command '%s' as '%s'",
@@ -4576,8 +4533,7 @@ void do_perl(struct st_command *command)
/* Create temporary file name */
if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
- "tmp", O_CREAT | O_SHARE | O_RDWR,
- MYF(MY_WME))) < 0)
+ "tmp", O_SHARE, MYF(MY_WME))) < 0)
die("Failed to create temporary file for perl command");
my_close(fd, MYF(0));
@@ -5027,11 +4983,34 @@ int query_get_string(MYSQL* mysql, const char* query,
}
+#ifdef _WIN32
+#define SIGKILL 9
+#include <my_minidump.h>
static int my_kill(int pid, int sig)
{
-#ifdef _WIN32
HANDLE proc;
- if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL)
+ if (sig == SIGABRT)
+ {
+ /*
+ Create a minidump. If process is being debugged, debug break
+ Otherwise, terminate.
+ */
+ verbose_msg("Aborting %d",pid);
+ my_create_minidump(pid,TRUE);
+ proc= OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+ if(!proc)
+ return -1;
+ BOOL debugger_present;
+ if (CheckRemoteDebuggerPresent(proc,&debugger_present) && debugger_present)
+ {
+ if (DebugBreakProcess(proc))
+ {
+ CloseHandle(proc);
+ return 0;
+ }
+ }
+ }
+ else if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL)
return -1;
if (sig == 0)
{
@@ -5042,12 +5021,30 @@ static int my_kill(int pid, int sig)
(void)TerminateProcess(proc, 201);
CloseHandle(proc);
return 1;
-#else
- return kill(pid, sig);
-#endif
}
+/* Wait until process is gone, with timeout */
+static int wait_until_dead(int pid, int timeout)
+{
+ HANDLE proc= OpenProcess(SYNCHRONIZE, FALSE, pid);
+ if (!proc)
+ return 0; /* already dead */
+ DBUG_ASSERT(timeout >= 0);
+ DBUG_ASSERT(timeout <= UINT_MAX/1000);
+ DWORD wait_result= WaitForSingleObject(proc, (DWORD)timeout*1000);
+ CloseHandle(proc);
+ return (int)wait_result;
+}
+
+#else /* !_WIN32 */
+
+
+static int my_kill(int pid, int sig)
+{
+ DBUG_PRINT("info", ("Killing server, pid: %d", pid));
+ return kill(pid, sig);
+}
/*
Shutdown the server of current connection and
@@ -5064,6 +5061,27 @@ static int my_kill(int pid, int sig)
*/
+
+static int wait_until_dead(int pid, int timeout)
+{
+ DBUG_ENTER("wait_until_dead");
+ /* Check that server dies */
+ while (timeout--)
+ {
+ if (my_kill(pid, 0) < 0)
+ {
+ DBUG_PRINT("info", ("Process %d does not exist anymore", pid));
+ DBUG_RETURN(0);
+ }
+ DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
+ /* Sleep one second */
+ my_sleep(1000000L);
+ }
+ DBUG_RETURN(1); // Did not die
+}
+#endif /* _WIN32 */
+
+
void do_shutdown_server(struct st_command *command)
{
long timeout= opt_wait_for_pos_timeout ? opt_wait_for_pos_timeout / 5 : 300;
@@ -5117,24 +5135,31 @@ void do_shutdown_server(struct st_command *command)
}
DBUG_PRINT("info", ("Got pid %d", pid));
- /* Tell server to shutdown if timeout > 0*/
+ /*
+ If timeout == 0, it means we should kill the server hard, without
+ any shutdown or core (SIGKILL)
+
+ If timeout is given, then we do things in the following order:
+ - mysql_shutdown()
+ - If server is not dead within timeout
+ - kill SIGABRT (to get a core)
+ - If server is not dead within new timeout
+ - kill SIGKILL
+ */
+
if (timeout && mysql_shutdown(mysql, SHUTDOWN_DEFAULT))
die("mysql_shutdown failed");
- /* Check that server dies */
- while(timeout--){
- if (my_kill(pid, 0) < 0){
- DBUG_PRINT("info", ("Process %d does not exist anymore", pid));
- DBUG_VOID_RETURN;
+ if (!timeout || wait_until_dead(pid, timeout))
+ {
+ if (timeout)
+ (void) my_kill(pid, SIGABRT);
+ /* Give server a few seconds to die in all cases */
+ if (!timeout || wait_until_dead(pid, timeout < 5 ? 5 : timeout))
+ {
+ (void) my_kill(pid, SIGKILL);
}
- DBUG_PRINT("info", ("Sleeping, timeout: %ld", timeout));
- my_sleep(1000000L);
}
-
- /* Kill the server */
- DBUG_PRINT("info", ("Killing server, pid: %d", pid));
- (void)my_kill(pid, 9);
-
DBUG_VOID_RETURN;
}
@@ -6441,7 +6466,7 @@ static void do_reset_connection()
}
-my_bool match_delimiter(int c, const char *delim, uint length)
+my_bool match_delimiter(int c, const char *delim, size_t length)
{
uint i;
char tmp[MAX_DELIMITER_LENGTH];
@@ -6869,6 +6894,7 @@ int read_command(struct st_command** command_ptr)
if (parser.current_line < parser.read_lines)
{
get_dynamic(&q_lines, command_ptr, parser.current_line) ;
+ DBUG_PRINT("info", ("query: %s", (*command_ptr)->query));
DBUG_RETURN(0);
}
if (!(*command_ptr= command=
@@ -7302,7 +7328,7 @@ int parse_args(int argc, char **argv)
append - append to file instead of overwriting old file
*/
-void str_to_file2(const char *fname, char *str, int size, my_bool append)
+void str_to_file2(const char *fname, char *str, size_t size, my_bool append)
{
int fd;
char buff[FN_REFLEN];
@@ -7336,7 +7362,7 @@ void str_to_file2(const char *fname, char *str, int size, my_bool append)
size - size of content witten to file
*/
-void str_to_file(const char *fname, char *str, int size)
+void str_to_file(const char *fname, char *str, size_t size)
{
str_to_file2(fname, str, size, FALSE);
}
@@ -7863,7 +7889,7 @@ static void handle_no_active_connection(struct st_command *command,
*/
void run_query_normal(struct st_connection *cn, struct st_command *command,
- int flags, char *query, int query_len,
+ int flags, char *query, size_t query_len,
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= 0;
@@ -8208,7 +8234,7 @@ void handle_no_error(struct st_command *command)
*/
void run_query_stmt(struct st_connection *cn, struct st_command *command,
- char *query, int query_len, DYNAMIC_STRING *ds,
+ char *query, size_t query_len, DYNAMIC_STRING *ds,
DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
@@ -8495,7 +8521,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
DYNAMIC_STRING ds_sorted;
DYNAMIC_STRING ds_warnings;
char *query;
- int query_len;
+ size_t query_len;
my_bool view_created= 0, sp_created= 0;
my_bool complete_query= ((flags & QUERY_SEND_FLAG) &&
(flags & QUERY_REAP_FLAG));
@@ -8551,7 +8577,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
if (!disable_query_log && (flags & QUERY_SEND_FLAG))
{
char *print_query= query;
- int print_len= query_len;
+ size_t print_len= query_len;
if (flags & QUERY_PRINT_ORIGINAL_FLAG)
{
print_query= command->query;
@@ -8748,7 +8774,7 @@ void init_re_comp(regex_t *re, const char* str)
if (err)
{
char erbuf[100];
- int len= regerror(err, re, erbuf, sizeof(erbuf));
+ size_t len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8853,7 +8879,7 @@ int match_re(regex_t *re, char *str)
{
char erbuf[100];
- int len= regerror(err, re, erbuf, sizeof(erbuf));
+ size_t len= regerror(err, re, erbuf, sizeof(erbuf));
die("error %s, %d/%d `%s'\n",
re_eprint(err), (int)len, (int)sizeof(erbuf), erbuf);
}
@@ -8998,7 +9024,7 @@ static void dump_backtrace(void)
#endif
}
fputs("Attempting backtrace...\n", stderr);
- my_print_stacktrace(NULL, (ulong)my_thread_stack_size);
+ my_print_stacktrace(NULL, (ulong)my_thread_stack_size, 0);
}
#else
@@ -9152,17 +9178,14 @@ int main(int argc, char **argv)
init_builtin_echo();
#ifdef _WIN32
-#ifndef USE_CYGWIN
is_windows= 1;
-#endif
- init_tmp_sh_file();
init_win_path_patterns();
#endif
read_command_buf= (char*)my_malloc(read_command_buflen= 65536, MYF(MY_FAE));
init_dynamic_string(&ds_res, "", 2048, 2048);
- init_alloc_root(&require_file_root, 1024, 1024, MYF(0));
+ init_alloc_root(&require_file_root, "require_file", 1024, 1024, MYF(0));
parse_args(argc, argv);
@@ -9995,8 +10018,7 @@ typedef struct st_replace_found {
void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
- const char *str,
- int len __attribute__((unused)))
+ const char *str)
{
REPLACE *rep_pos;
REPLACE_STRING *rep_str;
@@ -10039,7 +10061,6 @@ void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
DBUG_PRINT("exit", ("Found end of from string"));
DBUG_VOID_RETURN;
}
- DBUG_ASSERT(from <= str+len);
start= from;
rep_pos=rep;
}
@@ -10103,7 +10124,7 @@ struct st_replace_regex* init_replace_regex(char* expr)
{
char *expr_end, *buf_p;
struct st_replace_regex* res;
- uint expr_len= strlen(expr);
+ size_t expr_len= strlen(expr);
/* my_malloc() will die on fail with MY_FAE */
res=(struct st_replace_regex*)my_malloc(
@@ -10153,7 +10174,7 @@ void append_replace_regex(char* expr, char *expr_end, struct st_replace_regex* r
/* Allow variable for the *entire* list of replacements */
if (*p == '$')
{
- const char *v_end;
+ const char *v_end= 0;
VAR *val= var_get(p, &v_end, 0, 1);
if (val)
@@ -10487,7 +10508,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
regfree(&r);
*res_p= 0;
*buf_p= buf;
- *buf_len_p= buf_len;
+ *buf_len_p= (int)buf_len;
return 0;
}
@@ -10794,7 +10815,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
for (i=1 ; i <= found_sets ; i++)
{
pos=from[found_set[i-1].table_offset];
- rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1;
+ rep_str[i].found= !strncmp(pos, "\\^", 3) ? 2 : 1;
rep_str[i].replace_string=to_array[found_set[i-1].table_offset];
rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos);
rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+
@@ -11106,13 +11127,16 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len)
{
/* Convert to lower case, and do this first */
char *c= lower;
- for (const char *v= val; *v; v++)
+ for (const char *v= val, *end_v= v + len; v < end_v; v++)
*c++= my_tolower(charset_info, *v);
*c= '\0';
/* Copy from this buffer instead */
}
else
- memcpy(lower, val, len+1);
+ {
+ memcpy(lower, val, len);
+ lower[len]= 0;
+ }
fix_win_paths(lower, len);
val= lower;
}
@@ -11130,7 +11154,7 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, size_t len)
if (glob_replace)
{
/* Normal replace */
- replace_strings_append(glob_replace, ds, val, len);
+ replace_strings_append(glob_replace, ds, val);
}
else
dynstr_append_mem(ds, val, len);