MWL#36: Add a mysqlbinlog option to change the used database.
Add rewrite_db() member to the Table_map_log_event class. Each RBR-event in binary log is preceded by a Table_map event containing a (db_id, db_name) pair. The rewrite_db(new_name) function replaces db_name by new_name in a buffer containing Table_map event read from the binary log.
This commit is contained in:
parent
6bc7eab161
commit
ef5874d154
@ -8005,6 +8005,100 @@ Table_map_log_event::~Table_map_log_event()
|
||||
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
/*
|
||||
Reset db name. This function assumes that temp_buf member contains event
|
||||
representation taken from a binary log. It resets m_dbnam and m_dblen and
|
||||
rewrites temp_buf with new db name.
|
||||
On success returns 0, on failure return non-zero value.
|
||||
*/
|
||||
int Table_map_log_event::rewrite_db(
|
||||
const char* new_db,
|
||||
size_t new_len,
|
||||
const Format_description_log_event* desc)
|
||||
{
|
||||
DBUG_ENTER("Table_map_log_event::rewrite_db");
|
||||
DBUG_ASSERT(temp_buf);
|
||||
|
||||
uint header_len= min(desc->common_header_len,
|
||||
LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN;
|
||||
int len_diff;
|
||||
|
||||
if (!(len_diff= new_len - m_dblen))
|
||||
{
|
||||
memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1);
|
||||
memcpy((void*) m_dbnam, new_db, m_dblen + 1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
// Create new temp_buf
|
||||
ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET);
|
||||
ulong event_new_len= event_cur_len + len_diff;
|
||||
char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME));
|
||||
|
||||
if (!new_temp_buf)
|
||||
{
|
||||
sql_print_error("Table_map_log_event::rewrite_dbname: "
|
||||
"failed to allocate new temp_buf (%d bytes required)", event_new_len);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
// Rewrite temp_buf
|
||||
char* ptr= new_temp_buf;
|
||||
ulong cnt= 0;
|
||||
|
||||
// Copy header and change event length
|
||||
memcpy(ptr, temp_buf, header_len);
|
||||
int4store(ptr + EVENT_LEN_OFFSET, event_new_len);
|
||||
ptr += header_len;
|
||||
cnt += header_len;
|
||||
|
||||
// Write new db name length and new name
|
||||
*ptr++ = new_len;
|
||||
memcpy(ptr, new_db, new_len + 1);
|
||||
ptr += new_len + 1;
|
||||
cnt += m_dblen + 2;
|
||||
|
||||
// Copy rest part
|
||||
memcpy(ptr, temp_buf + cnt, event_cur_len - cnt);
|
||||
|
||||
// Reregister temp buf
|
||||
free_temp_buf();
|
||||
register_temp_buf(new_temp_buf);
|
||||
|
||||
// Reset m_dbnam and m_dblen members
|
||||
m_dblen= new_len;
|
||||
|
||||
// m_dbnam resides in m_memory together with m_tblnam and m_coltype
|
||||
uchar* memory= m_memory;
|
||||
char const* tblnam= m_tblnam;
|
||||
uchar* coltype= m_coltype;
|
||||
|
||||
m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
|
||||
&m_dbnam, (uint) m_dblen + 1,
|
||||
&m_tblnam, (uint) m_tbllen + 1,
|
||||
&m_coltype, (uint) m_colcnt,
|
||||
NullS);
|
||||
|
||||
if (!m_memory)
|
||||
{
|
||||
sql_print_error("Table_map_log_event::rewrite_dbname: "
|
||||
"failed to allocate new m_memory (%d + %d + %d bytes required)",
|
||||
m_dblen + 1, m_tbllen + 1, m_colcnt);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
memcpy((void*)m_dbnam, new_db, m_dblen + 1);
|
||||
memcpy((void*)m_tblnam, tblnam, m_tbllen + 1);
|
||||
memcpy(m_coltype, coltype, m_colcnt);
|
||||
|
||||
my_free(memory, MYF(MY_WME));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
Return value is an error code, one of:
|
||||
|
||||
|
@ -3310,6 +3310,8 @@ public:
|
||||
ulong get_table_id() const { return m_table_id; }
|
||||
const char *get_table_name() const { return m_tblnam; }
|
||||
const char *get_db_name() const { return m_dbnam; }
|
||||
int rewrite_db(const char* new_name, size_t new_name_len,
|
||||
const Format_description_log_event*);
|
||||
#endif
|
||||
|
||||
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user