diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
commit | 65ca700def99289cc31a7040537f5aa6e12bf485 (patch) | |
tree | 97b3a07299b626c519da0e80c122b5b79b933914 /client/mysqlbinlog.cc | |
parent | 2ab57de38d13d927ddff2d51aed4af34e13998f5 (diff) | |
parent | 6e5bcca7935d3c62f84bb640e5357664a210ee12 (diff) | |
download | mariadb-git-65ca700def99289cc31a7040537f5aa6e12bf485.tar.gz |
merge.
checkpoint.
does not compile.
Diffstat (limited to 'client/mysqlbinlog.cc')
-rw-r--r-- | client/mysqlbinlog.cc | 150 |
1 files changed, 142 insertions, 8 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 277c2d62544..a8f96a1089d 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -35,6 +35,15 @@ #include "log_event.h" #include "sql_common.h" +/* Needed for Rpl_filter */ +CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci; + +#include "sql_string.h" // needed for Rpl_filter +#include "sql_list.h" // needed for Rpl_filter +#include "rpl_filter.h" + +Rpl_filter *binlog_filter; + #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -436,7 +445,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ptr= fname + target_dir_name_len; memcpy(ptr,bname,blen); ptr+= blen; - ptr+= sprintf(ptr, "-%x", file_id); + ptr+= my_sprintf(ptr, (ptr, "-%x", file_id)); if ((file= create_unique_file(fname,ptr)) < 0) { @@ -626,6 +635,42 @@ static bool shall_skip_database(const char *log_dbname) /** + Print "use <db>" statement when current db is to be changed. + + We have to control emiting USE statements according to rewrite-db options. + We have to do it here (see process_event() below) and to suppress + producing USE statements by corresponding log event print-functions. +*/ + +void print_use_stmt(PRINT_EVENT_INFO* pinfo, const char* db, size_t db_len) +{ + // pinfo->db is the current db. + // If current db is the same as required db, do nothing. + if (!db || !memcmp(pinfo->db, db, db_len + 1)) + return; + + // Current db and required db are different. + // Check for rewrite rule for required db. (Note that in a rewrite rule + // neither db_from nor db_to part can be empty). + size_t len_to= 0; + const char *db_to= binlog_filter->get_rewrite_db(db, &len_to); + + // If there is no rewrite rule for db (in this case len_to is left = 0), + // printing of the corresponding USE statement is left for log event + // print-function. + if (!len_to) + return; + + // In case of rewrite rule print USE statement for db_to + fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter); + + // Copy the *original* db to pinfo to suppress emiting + // of USE stmts by log_event print-functions. + memcpy(pinfo->db, db, db_len + 1); +} + + +/** Prints the given event in base64 format. The header is printed to the head cache and the body is printed to @@ -736,9 +781,11 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, switch (ev_type) { case QUERY_EVENT: - if (!((Query_log_event*)ev)->is_trans_keyword() && - shall_skip_database(((Query_log_event*)ev)->db)) + { + Query_log_event *qe= (Query_log_event*)ev; + if (!qe->is_trans_keyword() && shall_skip_database(qe->db)) goto end; + print_use_stmt(print_event_info, qe->db, qe->db_len); if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { if ((retval= write_event_header_and_base64(ev, result_file, @@ -749,6 +796,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else ev->print(result_file, print_event_info); break; + } case CREATE_FILE_EVENT: { @@ -876,6 +924,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, if (!shall_skip_database(exlq->db)) { + print_use_stmt(print_event_info, exlq->db, exlq->db_len); if (fname) { convert_path_to_forward_slashes(fname); @@ -899,6 +948,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; goto end; } + size_t len_to= 0; + const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); + if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) + { + error("Could not rewrite database name"); + goto err; + } } case WRITE_ROWS_EVENT: case DELETE_ROWS_EVENT: @@ -983,14 +1039,16 @@ err: retval= ERROR_STOP; end: rec_count++; + /* - Destroy the log_event object. If reading from a remote host, - set the temp_buf to NULL so that memory isn't freed twice. + Destroy the log_event object. + MariaDB MWL#36: mainline does this: + If reading from a remote host, + set the temp_buf to NULL so that memory isn't freed twice. + We no longer do that, we use Rpl_filter::event_owns_temp_buf instead. */ if (ev) { - if (remote_opt) - ev->temp_buf= 0; if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev; } @@ -1147,6 +1205,10 @@ that may lead to an endless loop.", "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"rewrite-db", OPT_REWRITE_DB, + "Updates to a database with a different name than the original. \ +Example: rewrite-db='from->to'.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1330,6 +1392,53 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); } break; + case OPT_REWRITE_DB: // db_from->db_to + { + /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ + char* ptr; + char* key= argument; // db-from + char* val; // db-to + + // Where key begins + while (*key && my_isspace(&my_charset_latin1, *key)) + key++; + + // Where val begins + if (!(ptr= strstr(argument, "->"))) + { + sql_print_error("Bad syntax in rewrite-db: missing '->'!\n"); + return 1; + } + val= ptr + 2; + while (*val && my_isspace(&my_charset_latin1, *val)) + val++; + + // Write \0 and skip blanks at the end of key + *ptr-- = 0; + while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument) + *ptr-- = 0; + + if (!*key) + { + sql_print_error("Bad syntax in rewrite-db: empty db-from!\n"); + return 1; + } + + // Skip blanks at the end of val + ptr= val; + while (*ptr && !my_isspace(&my_charset_latin1, *ptr)) + ptr++; + *ptr= 0; + + if (!*val) + { + sql_print_error("Bad syntax in rewrite-db: empty db-to!\n"); + return 1; + } + + binlog_filter->add_db_rewrite(key, val); + break; + } case 'v': if (argument == disabled_my_option) verbose= 0; @@ -1374,6 +1483,10 @@ static int parse_args(int *argc, char*** argv) */ static Exit_status safe_connect() { + /* Close and old connections to MySQL */ + if (mysql) + mysql_close(mysql); + mysql= mysql_init(NULL); if (!mysql) @@ -1599,7 +1712,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, If reading from a remote host, ensure the temp_buf for the Log_event class is pointing to the incoming stream. */ - ev->register_temp_buf((char *) net->read_pos + 1); + ev->register_temp_buf((char *) net->read_pos + 1, FALSE); Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || @@ -1999,6 +2112,8 @@ end: return retval; } +/* Used in sql_alloc(). Inited and freed in main() */ +MEM_ROOT s_mem_root; int main(int argc, char** argv) { @@ -2011,8 +2126,16 @@ int main(int argc, char** argv) my_init_time(); // for time functions + init_alloc_root(&s_mem_root, 16384, 0); + if (!(binlog_filter= new Rpl_filter)) + { + error("Failed to create Rpl_filter"); + exit(1); + } + if (load_defaults("my", load_default_groups, &argc, &argv)) exit(1); + defaults_argv= argv; parse_args(&argc, (char***)&argv); @@ -2100,6 +2223,8 @@ int main(int argc, char** argv) if (result_file != stdout) my_fclose(result_file, MYF(0)); cleanup(); + delete binlog_filter; + free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); @@ -2111,6 +2236,12 @@ int main(int argc, char** argv) DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } + +void *sql_alloc(size_t size) +{ + return alloc_root(&s_mem_root, size); +} + /* We must include this here as it's compiled with different options for the server @@ -2122,3 +2253,6 @@ int main(int argc, char** argv) #include "log_event.cc" #include "log_event_old.cc" #include "rpl_utility.cc" +#include "sql_string.cc" +#include "sql_list.cc" +#include "rpl_filter.cc" |