=== modified file 'sql/log_event.cc' --- sql/log_event.cc 2012-05-07 20:20:42 +0000 +++ sql/log_event.cc 2012-06-20 18:43:43 +0000 @@ -8581,7 +8581,18 @@ DBUG_RETURN(HA_ERR_OUT_OF_MEM); strmov(db_mem, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len)); - strmov(tname_mem, m_tblnam); + + const char* rewritten_tbl= rpl_filter->get_rewrite_table(db_mem, m_tblnam, &dummy_len); + if (rewritten_tbl == NULL) + { + strmov(tname_mem, m_tblnam); + } + else + { + char *p= strchr(rewritten_tbl, '.'); + strmake(db_mem, rewritten_tbl, p - rewritten_tbl); + strmov(tname_mem, p + 1); + } table_list->init_one_table(db_mem, strlen(db_mem), tname_mem, strlen(tname_mem), === modified file 'sql/mysqld.cc' --- sql/mysqld.cc 2012-05-07 20:20:42 +0000 +++ sql/mysqld.cc 2012-06-20 18:43:43 +0000 @@ -5924,6 +5924,10 @@ "Updates to a database with a different name than the original. Example: " "replicate-rewrite-db=master_db_name->slave_db_name.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-wild-rewrite-table", OPT_REPLICATE_WILD_REWRITE_TABLE, + "Updates to a table with a different name than the original (match the specified wildcard pattern). Example: " + "replicate-wild-rewrite-table=master_table_spec->slave_table_name.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_REPLICATION {"replicate-same-server-id", 0, "In replication, if set to 1, do not skip events having our server id. " @@ -6982,6 +6986,7 @@ rpl_filter->add_do_db(argument); break; } + case (int)OPT_REPLICATE_WILD_REWRITE_TABLE: case (int)OPT_REPLICATE_REWRITE_DB: { char* key = argument,*p, *val; @@ -7009,7 +7014,10 @@ return 1; } - rpl_filter->add_db_rewrite(key, val); + if (optid == OPT_REPLICATE_REWRITE_DB) + rpl_filter->add_db_rewrite(key, val); + else if (optid == OPT_REPLICATE_WILD_REWRITE_TABLE) + rpl_filter->add_wild_table_rewrite(key, val); break; } === modified file 'sql/mysqld.h' --- sql/mysqld.h 2012-04-27 17:07:53 +0000 +++ sql/mysqld.h 2012-06-20 18:43:43 +0000 @@ -389,6 +389,7 @@ OPT_REPLICATE_IGNORE_DB, OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_REWRITE_DB, + OPT_REPLICATE_WILD_REWRITE_TABLE, OPT_REPLICATE_WILD_DO_TABLE, OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_SAFE, === modified file 'sql/rpl_filter.cc' --- sql/rpl_filter.cc 2011-06-30 15:46:53 +0000 +++ sql/rpl_filter.cc 2012-06-20 18:43:43 +0000 @@ -23,8 +23,8 @@ #define TABLE_RULE_ARR_SIZE 16 Rpl_filter::Rpl_filter() : - table_rules_on(0), do_table_inited(0), ignore_table_inited(0), - wild_do_table_inited(0), wild_ignore_table_inited(0) + table_rules_on(0) ,table_rewrite_on(0), do_table_inited(0), ignore_table_inited(0), + wild_do_table_inited(0), wild_ignore_table_inited(0), wild_rewrite_table_inited(0) { do_db.empty(); ignore_db.empty(); @@ -42,6 +42,8 @@ free_string_array(&wild_do_table); if (wild_ignore_table_inited) free_string_array(&wild_ignore_table); + if (wild_rewrite_table_inited) + free_string_array(&wild_rewrite_table); free_list(&do_db); free_list(&ignore_db); free_list(&rewrite_db); @@ -286,7 +288,6 @@ table_rules_on= 1; DBUG_RETURN(add_wild_table_rule(&wild_do_table, table_spec)); } - int Rpl_filter::add_wild_ignore_table(const char* table_spec) @@ -298,6 +299,13 @@ DBUG_RETURN(add_wild_table_rule(&wild_ignore_table, table_spec)); } +void Rpl_filter::add_wild_table_rewrite(const char* from_tbl_spec, const char * to_tbl) +{ + if (!wild_rewrite_table_inited) + init_table_rule_array(&wild_rewrite_table, &wild_rewrite_table_inited); + table_rewrite_on= 1; + add_wild_table_rule(&wild_rewrite_table, from_tbl_spec, to_tbl); +} void Rpl_filter::add_db_rewrite(const char* from_db, const char* to_db) @@ -331,18 +339,27 @@ */ int -Rpl_filter::add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec) +Rpl_filter::add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec, const char* target_tbl) { const char* dot = strchr(table_spec, '.'); if (!dot) return 1; uint len = (uint)strlen(table_spec); + uint target_len= target_tbl ? (uint)strlen(target_tbl) : 0; + TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT) - + len, MYF(MY_WME)); + + len + target_len + 1, MYF(MY_WME)); if (!e) return 1; e->db= (char*)e + sizeof(TABLE_RULE_ENT); e->tbl_name= e->db + (dot - table_spec) + 1; e->key_len= len; memcpy(e->db, table_spec, len); + + if (target_tbl) + { + e->target_tbl= e->db + len; + memcpy(e->target_tbl, target_tbl, target_len + 1); + } + return insert_dynamic(a, (uchar*)&e); } @@ -536,6 +553,27 @@ return db; } +const char* +Rpl_filter::get_rewrite_table(const char* db, const char *tbl, size_t *new_len) +{ + if (!wild_rewrite_table_inited) + return NULL; + + char hash_key[2*NAME_LEN+2]; + char *end; + + end= strmov(hash_key, db); + *end++= '.'; + uint len= (uint)(strmov(end, tbl) - hash_key); + + TABLE_RULE_ENT *e= find_wild(&wild_rewrite_table, hash_key, len); + + if (!e) + return NULL; + + *new_len= strlen(e->target_tbl); + return e->target_tbl; +} I_List* Rpl_filter::get_do_db() === modified file 'sql/rpl_filter.h' --- sql/rpl_filter.h 2011-06-30 15:46:53 +0000 +++ sql/rpl_filter.h 2012-06-20 18:43:43 +0000 @@ -29,6 +29,7 @@ char* db; char* tbl_name; uint key_len; + char *target_tbl; } TABLE_RULE_ENT; /* @@ -61,6 +62,7 @@ int add_wild_do_table(const char* table_spec); int add_wild_ignore_table(const char* table_spec); + void add_wild_table_rewrite(const char* from_tbl_spec, const char* to_tbl); void add_do_db(const char* db_spec); void add_ignore_db(const char* db_spec); @@ -76,18 +78,20 @@ void get_wild_ignore_table(String* str); const char* get_rewrite_db(const char* db, size_t *new_len); + const char* get_rewrite_table(const char* db, const char *tbl, size_t *new_len); I_List* get_do_db(); I_List* get_ignore_db(); private: bool table_rules_on; + bool table_rewrite_on; void init_table_rule_hash(HASH* h, bool* h_inited); void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited); int add_table_rule(HASH* h, const char* table_spec); - int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); + int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec, const char* target_table=NULL); void free_string_array(DYNAMIC_ARRAY *a); @@ -104,11 +108,13 @@ HASH ignore_table; DYNAMIC_ARRAY wild_do_table; DYNAMIC_ARRAY wild_ignore_table; + DYNAMIC_ARRAY wild_rewrite_table; bool do_table_inited; bool ignore_table_inited; bool wild_do_table_inited; bool wild_ignore_table_inited; + bool wild_rewrite_table_inited; I_List do_db; I_List ignore_db;