Commit ef5874d1 authored by Alexander Ivanov's avatar Alexander Ivanov

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.
parent 6bc7eab1
...@@ -8005,6 +8005,100 @@ Table_map_log_event::~Table_map_log_event() ...@@ -8005,6 +8005,100 @@ Table_map_log_event::~Table_map_log_event()
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR)); 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: Return value is an error code, one of:
......
...@@ -3310,6 +3310,8 @@ public: ...@@ -3310,6 +3310,8 @@ public:
ulong get_table_id() const { return m_table_id; } ulong get_table_id() const { return m_table_id; }
const char *get_table_name() const { return m_tblnam; } const char *get_table_name() const { return m_tblnam; }
const char *get_db_name() const { return m_dbnam; } 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 #endif
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment