Merge lp:~tsarev/percona-server/5.1-18205_02_wl36.patch into lp:percona-server/5.1

Proposed by Oleg Tsarev
Status: Superseded
Proposed branch: lp:~tsarev/percona-server/5.1-18205_02_wl36.patch
Merge into: lp:percona-server/5.1
Diff against target: 1037 lines (+572/-29)
24 files modified
Percona-Server/client/Makefile.am (+3/-1)
Percona-Server/client/client_priv.h (+1/-0)
Percona-Server/client/mysqlbinlog.cc (+159/-9)
Percona-Server/client/sql_string.cc (+0/-9)
Percona-Server/client/sql_string.h (+5/-0)
Percona-Server/mysql-test/include/wl36.inc (+51/-0)
Percona-Server/mysql-test/r/mysqlbinlog.result (+2/-6)
Percona-Server/mysql-test/r/wl36-mixed.result (+48/-0)
Percona-Server/mysql-test/r/wl36-row.result (+48/-0)
Percona-Server/mysql-test/r/wl36-statement.result (+48/-0)
Percona-Server/mysql-test/t/wl36-mixed.test (+3/-0)
Percona-Server/mysql-test/t/wl36-row.test (+3/-0)
Percona-Server/mysql-test/t/wl36-statement.test (+3/-0)
Percona-Server/sql/log_event.cc (+106/-1)
Percona-Server/sql/log_event.h (+16/-2)
Percona-Server/sql/mysql_priv.h (+4/-0)
Percona-Server/sql/mysqld.cc (+1/-0)
Percona-Server/sql/rpl_filter.cc (+9/-0)
Percona-Server/sql/rpl_filter.h (+4/-1)
Percona-Server/sql/sql_string.cc (+3/-0)
Percona-Server/sql/sql_string.h (+9/-0)
Percona-Server/sql/thr_malloc.cc (+2/-0)
doc/source/flexibility/mysqlbinlog_change_db.rst (+43/-0)
doc/source/index.rst (+1/-0)
To merge this branch: bzr merge lp:~tsarev/percona-server/5.1-18205_02_wl36.patch
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Needs Information
Review via email: mp+91985@code.launchpad.net

This proposal has been superseded by a proposal from 2012-02-09.

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

For the feature branch to go in, it needs an associated blueprint on Launchpad.

review: Needs Information

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Percona-Server/client/Makefile.am'
2--- Percona-Server/client/Makefile.am 2011-07-03 15:47:37 +0000
3+++ Percona-Server/client/Makefile.am 2012-02-09 15:07:20 +0000
4@@ -24,6 +24,7 @@
5 INCLUDES = -I$(top_builddir)/include \
6 -I$(top_srcdir)/include \
7 -I$(top_srcdir)/regex \
8+ -I$(top_srcdir)/sql \
9 $(openssl_includes)
10
11 LIBS = @CLIENT_LIBS@
12@@ -107,7 +108,8 @@
13 rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
14 log_event.cc my_decimal.h my_decimal.cc \
15 log_event_old.h log_event_old.cc \
16- rpl_record_old.h rpl_record_old.cc
17+ rpl_record_old.h rpl_record_old.cc \
18+ sql_list.h rpl_filter.h sql_list.cc rpl_filter.cc
19 strings_src=decimal.c
20
21 link_sources:
22
23=== modified file 'Percona-Server/client/client_priv.h'
24--- Percona-Server/client/client_priv.h 2011-11-24 02:01:33 +0000
25+++ Percona-Server/client/client_priv.h 2012-02-09 15:07:20 +0000
26@@ -97,6 +97,7 @@
27 OPT_SYSLOG,
28 #endif
29 OPT_FIRST_SLAVE,
30+ OPT_REWRITE_DB,
31 OPT_ALL,
32 OPT_NO_REMOVE_EOL_CARRET,
33 OPT_INNODB_OPTIMIZE_KEYS,
34
35=== modified file 'Percona-Server/client/mysqlbinlog.cc'
36--- Percona-Server/client/mysqlbinlog.cc 2011-07-11 16:13:27 +0000
37+++ Percona-Server/client/mysqlbinlog.cc 2012-02-09 15:07:20 +0000
38@@ -38,6 +38,15 @@
39 #include "sql_common.h"
40 #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
41
42+/* Needed for Rpl_filter */
43+CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci;
44+
45+#include "sql_string.h" // needed for Rpl_filter
46+#include "sql_list.h" // needed for Rpl_filter
47+#include "rpl_filter.h"
48+
49+Rpl_filter *binlog_filter;
50+
51 #define BIN_LOG_HEADER_SIZE 4
52 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
53
54@@ -623,6 +632,49 @@
55
56
57 /**
58+ Print "use <db>" statement when current db is to be changed.
59+
60+ We have to control emiting USE statements according to rewrite-db options.
61+ We have to do it here (see process_event() below) and to suppress
62+ producing USE statements by corresponding log event print-functions.
63+*/
64+void print_use_stmt(PRINT_EVENT_INFO* pinfo, const char* db, size_t db_len)
65+{
66+ /*
67+ pinfo->db is the current db.
68+ If current db is the same as required db, do nothing.
69+ */
70+ if (!db || !memcmp(pinfo->db, db, db_len + 1))
71+ return;
72+
73+ /*
74+ Current db and required db are different.
75+ Check for rewrite rule for required db. (Note that in a rewrite rule
76+ neither db_from nor db_to part can be empty)
77+ */
78+ size_t len_to= 0;
79+ const char* db_to= binlog_filter->get_rewrite_db(db, &len_to);
80+
81+ /*
82+ If there is no rewrite rule for db (in this case len_to is left = 0),
83+ printing of the corresponding USE statement is left for log event
84+ print-function.
85+ */
86+ if (!len_to)
87+ return;
88+
89+ // In case of rewrite rule print USE statement for db_to
90+ fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter);
91+
92+ /*
93+ Copy the *original* db to pinfo to suppress emiting
94+ of USE stmts by log_event print-functions.
95+ */
96+ memcpy(pinfo->db, db, db_len + 1);
97+}
98+
99+
100+/**
101 Prints the given event in base64 format.
102
103 The header is printed to the head cache and the body is printed to
104@@ -741,9 +793,22 @@
105
106 switch (ev_type) {
107 case QUERY_EVENT:
108- if (!((Query_log_event*)ev)->is_trans_keyword() &&
109- shall_skip_database(((Query_log_event*)ev)->db))
110- goto end;
111+ {
112+ Query_log_event *qe= (Query_log_event*)ev;
113+ if (!qe->is_trans_keyword())
114+ {
115+ if (shall_skip_database(qe->db))
116+ goto end;
117+ }
118+ else
119+ {
120+ /*
121+ In case the event for one of these statements is obtained
122+ from 5.0 binary log, make it compatible with 5.1.
123+ */
124+ ev->flags|= LOG_EVENT_SUPPRESS_USE_F;
125+ }
126+ print_use_stmt(print_event_info, qe->db, qe->db_len);
127 if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
128 {
129 if ((retval= write_event_header_and_base64(ev, result_file,
130@@ -754,6 +819,7 @@
131 else
132 ev->print(result_file, print_event_info);
133 break;
134+ }
135
136 case CREATE_FILE_EVENT:
137 {
138@@ -875,6 +941,7 @@
139
140 if (!shall_skip_database(exlq->db))
141 {
142+ print_use_stmt(print_event_info, exlq->db, exlq->db_len);
143 if (fname)
144 {
145 convert_path_to_forward_slashes(fname);
146@@ -898,6 +965,14 @@
147 destroy_evt= FALSE;
148 goto end;
149 }
150+ size_t len_to= 0;
151+ const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(),
152+ &len_to);
153+ if (len_to && map->rewrite_db(db_to, len_to, glob_description_event))
154+ {
155+ error("Could not rewrite database name");
156+ goto err;
157+ }
158 }
159 case WRITE_ROWS_EVENT:
160 case DELETE_ROWS_EVENT:
161@@ -983,15 +1058,19 @@
162 retval= ERROR_STOP;
163 end:
164 rec_count++;
165+
166+
167 /*
168- Destroy the log_event object. If reading from a remote host,
169- set the temp_buf to NULL so that memory isn't freed twice.
170+ Destroy the log_event object.
171+ MariaDB MWL#36: mainline does this:
172+ If reading from a remote host,
173+ set the temp_buf to NULL so that memory isn't freed twice.
174+ We no longer do that, we use Rpl_filter::event_owns_temp_buf instead.
175 */
176 if (ev)
177 {
178- if (remote_opt)
179- ev->temp_buf= 0;
180- if (destroy_evt) /* destroy it later if not set (ignored table map) */
181+ /* destroy it later if not set (ignored table map) */
182+ if (destroy_evt)
183 delete ev;
184 }
185 DBUG_RETURN(retval);
186@@ -1156,6 +1235,10 @@
187 "Used to reserve file descriptors for use by this program.",
188 &open_files_limit, &open_files_limit, 0, GET_ULONG,
189 REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
190+ {"rewrite-db", OPT_REWRITE_DB,
191+ "Updates to a database with a different name than the original. \
192+Example: rewrite-db='from->to'.",
193+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
194 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
195 };
196
197@@ -1347,6 +1430,53 @@
198 (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1);
199 }
200 break;
201+ case OPT_REWRITE_DB: // db_from->db_to
202+ {
203+ /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */
204+ char* ptr;
205+ char* key= argument; // db-from
206+ char* val; // db-to
207+
208+ // Where key begins
209+ while (*key && my_isspace(&my_charset_latin1, *key))
210+ key++;
211+
212+ // Where val begins
213+ if (!(ptr= strstr(argument, "->")))
214+ {
215+ sql_print_error("Bad syntax in rewrite-db: missing '->'!\n");
216+ return 1;
217+ }
218+ val= ptr + 2;
219+ while (*val && my_isspace(&my_charset_latin1, *val))
220+ val++;
221+
222+ // Write \0 and skip blanks at the end of key
223+ *ptr-- = 0;
224+ while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument)
225+ *ptr-- = 0;
226+
227+ if (!*key)
228+ {
229+ sql_print_error("Bad syntax in rewrite-db: empty db-from!\n");
230+ return 1;
231+ }
232+
233+ // Skip blanks at the end of val
234+ ptr= val;
235+ while (*ptr && !my_isspace(&my_charset_latin1, *ptr))
236+ ptr++;
237+ *ptr= 0;
238+
239+ if (!*val)
240+ {
241+ sql_print_error("Bad syntax in rewrite-db: empty db-to!\n");
242+ return 1;
243+ }
244+
245+ binlog_filter->add_db_rewrite(key, val);
246+ break;
247+ }
248 case 'v':
249 if (argument == disabled_my_option)
250 verbose= 0;
251@@ -1616,7 +1746,7 @@
252 If reading from a remote host, ensure the temp_buf for the
253 Log_event class is pointing to the incoming stream.
254 */
255- ev->register_temp_buf((char *) net->read_pos + 1);
256+ ev->register_temp_buf((char *) net->read_pos + 1, FALSE);
257
258 Log_event_type type= ev->get_type_code();
259 if (glob_description_event->binlog_version >= 3 ||
260@@ -2016,6 +2146,8 @@
261 return retval;
262 }
263
264+/* Used in sql_alloc(). Inited and freed in main() */
265+MEM_ROOT s_mem_root;
266
267 int main(int argc, char** argv)
268 {
269@@ -2028,6 +2160,13 @@
270
271 my_init_time(); // for time functions
272
273+ init_alloc_root(&s_mem_root, 16384, 0);
274+ if (!(binlog_filter= new Rpl_filter))
275+ {
276+ error("Failed to create Rpl_filter");
277+ exit(1);
278+ }
279+
280 if (load_defaults("my", load_default_groups, &argc, &argv))
281 exit(1);
282 defaults_argv= argv;
283@@ -2116,6 +2255,8 @@
284 if (result_file != stdout)
285 my_fclose(result_file, MYF(0));
286 cleanup();
287+ delete binlog_filter;
288+ free_root(&s_mem_root, MYF(0));
289 free_defaults(defaults_argv);
290 my_free_open_file_info();
291 load_processor.destroy();
292@@ -2127,6 +2268,12 @@
293 DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
294 }
295
296+
297+void *sql_alloc(size_t size)
298+{
299+ return alloc_root(&s_mem_root, size);
300+}
301+
302 /*
303 We must include this here as it's compiled with different options for
304 the server
305@@ -2137,4 +2284,7 @@
306 #include "my_decimal.cc"
307 #include "log_event.cc"
308 #include "log_event_old.cc"
309+#include "sql_string.cc"
310+#include "sql_list.cc"
311+#include "rpl_filter.cc"
312
313
314=== modified file 'Percona-Server/client/sql_string.cc'
315--- Percona-Server/client/sql_string.cc 2011-11-01 06:50:54 +0000
316+++ Percona-Server/client/sql_string.cc 2012-02-09 15:07:20 +0000
317@@ -28,15 +28,6 @@
318 #ifdef HAVE_FCONVERT
319 #include <floatingpoint.h>
320 #endif
321-
322-/*
323- The following extern declarations are ok as these are interface functions
324- required by the string function
325-*/
326-
327-extern void sql_alloc(size_t size);
328-extern void sql_element_free(void *ptr);
329-
330 #include "sql_string.h"
331
332 /*****************************************************************************
333
334=== modified file 'Percona-Server/client/sql_string.h'
335--- Percona-Server/client/sql_string.h 2011-06-30 15:37:13 +0000
336+++ Percona-Server/client/sql_string.h 2012-02-09 15:07:20 +0000
337@@ -17,6 +17,9 @@
338
339 /* This file is originally from the mysql distribution. Coded by monty */
340
341+#ifndef CLIENT_SQL_STRING_H
342+#define CLIENT_SQL_STRING_H
343+
344 #ifdef USE_PRAGMA_INTERFACE
345 #pragma interface /* gcc class implementation */
346 #endif
347@@ -359,3 +362,5 @@
348 return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
349 }
350 };
351+
352+#endif
353
354=== added file 'Percona-Server/mysql-test/include/wl36.inc'
355--- Percona-Server/mysql-test/include/wl36.inc 1970-01-01 00:00:00 +0000
356+++ Percona-Server/mysql-test/include/wl36.inc 2012-02-09 15:07:20 +0000
357@@ -0,0 +1,51 @@
358+#
359+# WL #36: http://askmonty.org/worklog/Server-Sprint/?tid=36
360+# This is basic test for --rewrite-db option.
361+# mysqlbinlog --rewrite-db="from->to" should rewrite database
362+#
363+
364+CREATE DATABASE a; USE a; CREATE TABLE t1(a INT);
365+CREATE DATABASE b; USE b; CREATE TABLE t1(b INT);
366+CREATE DATABASE c; USE c; CREATE TABLE t1(c INT);
367+
368+RESET MASTER;
369+--let MYSQLD_DATA_DIR=`select @@datadir`
370+--let BIN_LOG_FILE_NAME=query_get_value(show master status, File, 1)
371+--let BIN_LOG_START_POSITION=query_get_value(show master status, Position, 1)
372+USE a; INSERT INTO t1 VALUES(0);
373+USE b; INSERT INTO t1 VALUES(1);
374+--let BIN_LOG_STOP_POSITION=query_get_value(show master status, Position, 1)
375+FLUSH LOGS;
376+
377+--let BIN_LOG_FULL_PATH=`SELECT CONCAT("$MYSQLD_DATA_DIR", "$BIN_LOG_FILE_NAME")`
378+
379+--let i=3
380+# i=3: rewrite nothing
381+# i=2: rewrite a->c
382+# i=0: rewrite a->b
383+--disable_query_log
384+while ($i)
385+{
386+--let REWRITE=`SELECT CASE $i WHEN 3 THEN '' WHEN 2 THEN '--rewrite-db="a->c"' WHEN 1 THEN '--rewrite-db="a->b"' END`
387+
388+USE a; DELETE FROM t1;
389+USE b; DELETE FROM t1;
390+USE c; DELETE FROM t1;
391+
392+--echo #
393+--echo # Apply log with '$REWRITE'
394+--echo #
395+
396+--exec $MYSQL_BINLOG $REWRITE --start-position=$BIN_LOG_START_POSITION --stop-position=$BIN_LOG_STOP_POSITION $BIN_LOG_FULL_PATH | $MYSQL
397+
398+USE a; SELECT * FROM t1;
399+USE b; SELECT * FROM t1;
400+USE c; SELECT * FROM t1;
401+
402+dec $i;
403+}
404+--enable_query_log
405+
406+USE a; DROP TABLE t1; DROP DATABASE a;
407+USE b; DROP TABLE t1; DROP DATABASE b;
408+USE c; DROP TABLE t1; DROP DATABASE c;
409
410=== modified file 'Percona-Server/mysql-test/r/mysqlbinlog.result'
411--- Percona-Server/mysql-test/r/mysqlbinlog.result 2011-03-25 14:16:13 +0000
412+++ Percona-Server/mysql-test/r/mysqlbinlog.result 2012-02-09 15:07:20 +0000
413@@ -220,7 +220,6 @@
414 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
415 DELIMITER /*!*/;
416 ROLLBACK/*!*/;
417-use test/*!*/;
418 SET TIMESTAMP=1108844556/*!*/;
419 SET @@session.pseudo_thread_id=999999999/*!*/;
420 SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
421@@ -228,6 +227,7 @@
422 SET @@session.collation_database=DEFAULT/*!*/;
423 BEGIN
424 /*!*/;
425+use test/*!*/;
426 SET TIMESTAMP=1108844555/*!*/;
427 insert t1 values (1)
428 /*!*/;
429@@ -239,7 +239,6 @@
430 /*!40019 SET @@session.max_insert_delayed_threads=0*/;
431 /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
432 DELIMITER /*!*/;
433-use test/*!*/;
434 SET TIMESTAMP=1108844556/*!*/;
435 SET @@session.pseudo_thread_id=999999999/*!*/;
436 SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
437@@ -247,6 +246,7 @@
438 SET @@session.collation_database=DEFAULT/*!*/;
439 BEGIN
440 /*!*/;
441+use test/*!*/;
442 SET TIMESTAMP=1108844555/*!*/;
443 insert t1 values (1)
444 /*!*/;
445@@ -581,7 +581,6 @@
446 SET @@session.collation_database=DEFAULT/*!*/;
447 BEGIN
448 /*!*/;
449-use test/*!*/;
450 SET TIMESTAMP=1266652094/*!*/;
451 SavePoint mixed_cases
452 /*!*/;
453@@ -592,11 +591,9 @@
454 SET TIMESTAMP=1266652094/*!*/;
455 INSERT INTO db1.t1 VALUES(40)
456 /*!*/;
457-use test/*!*/;
458 SET TIMESTAMP=1266652094/*!*/;
459 ROLLBACK TO mixed_cases
460 /*!*/;
461-use db1/*!*/;
462 SET TIMESTAMP=1266652094/*!*/;
463 INSERT INTO db1.t2 VALUES("after rollback to")
464 /*!*/;
465@@ -624,7 +621,6 @@
466 SET @@session.collation_database=DEFAULT/*!*/;
467 BEGIN
468 /*!*/;
469-use test/*!*/;
470 SET TIMESTAMP=1266652094/*!*/;
471 SavePoint mixed_cases
472 /*!*/;
473
474=== added file 'Percona-Server/mysql-test/r/wl36-mixed.result'
475--- Percona-Server/mysql-test/r/wl36-mixed.result 1970-01-01 00:00:00 +0000
476+++ Percona-Server/mysql-test/r/wl36-mixed.result 2012-02-09 15:07:20 +0000
477@@ -0,0 +1,48 @@
478+CREATE DATABASE a;
479+USE a;
480+CREATE TABLE t1(a INT);
481+CREATE DATABASE b;
482+USE b;
483+CREATE TABLE t1(b INT);
484+CREATE DATABASE c;
485+USE c;
486+CREATE TABLE t1(c INT);
487+RESET MASTER;
488+USE a;
489+INSERT INTO t1 VALUES(0);
490+USE b;
491+INSERT INTO t1 VALUES(1);
492+FLUSH LOGS;
493+#
494+# Apply log with ''
495+#
496+a
497+0
498+b
499+1
500+c
501+#
502+# Apply log with '--rewrite-db="a->c"'
503+#
504+a
505+b
506+1
507+c
508+0
509+#
510+# Apply log with '--rewrite-db="a->b"'
511+#
512+a
513+b
514+0
515+1
516+c
517+USE a;
518+DROP TABLE t1;
519+DROP DATABASE a;
520+USE b;
521+DROP TABLE t1;
522+DROP DATABASE b;
523+USE c;
524+DROP TABLE t1;
525+DROP DATABASE c;
526
527=== added file 'Percona-Server/mysql-test/r/wl36-row.result'
528--- Percona-Server/mysql-test/r/wl36-row.result 1970-01-01 00:00:00 +0000
529+++ Percona-Server/mysql-test/r/wl36-row.result 2012-02-09 15:07:20 +0000
530@@ -0,0 +1,48 @@
531+CREATE DATABASE a;
532+USE a;
533+CREATE TABLE t1(a INT);
534+CREATE DATABASE b;
535+USE b;
536+CREATE TABLE t1(b INT);
537+CREATE DATABASE c;
538+USE c;
539+CREATE TABLE t1(c INT);
540+RESET MASTER;
541+USE a;
542+INSERT INTO t1 VALUES(0);
543+USE b;
544+INSERT INTO t1 VALUES(1);
545+FLUSH LOGS;
546+#
547+# Apply log with ''
548+#
549+a
550+0
551+b
552+1
553+c
554+#
555+# Apply log with '--rewrite-db="a->c"'
556+#
557+a
558+b
559+1
560+c
561+0
562+#
563+# Apply log with '--rewrite-db="a->b"'
564+#
565+a
566+b
567+0
568+1
569+c
570+USE a;
571+DROP TABLE t1;
572+DROP DATABASE a;
573+USE b;
574+DROP TABLE t1;
575+DROP DATABASE b;
576+USE c;
577+DROP TABLE t1;
578+DROP DATABASE c;
579
580=== added file 'Percona-Server/mysql-test/r/wl36-statement.result'
581--- Percona-Server/mysql-test/r/wl36-statement.result 1970-01-01 00:00:00 +0000
582+++ Percona-Server/mysql-test/r/wl36-statement.result 2012-02-09 15:07:20 +0000
583@@ -0,0 +1,48 @@
584+CREATE DATABASE a;
585+USE a;
586+CREATE TABLE t1(a INT);
587+CREATE DATABASE b;
588+USE b;
589+CREATE TABLE t1(b INT);
590+CREATE DATABASE c;
591+USE c;
592+CREATE TABLE t1(c INT);
593+RESET MASTER;
594+USE a;
595+INSERT INTO t1 VALUES(0);
596+USE b;
597+INSERT INTO t1 VALUES(1);
598+FLUSH LOGS;
599+#
600+# Apply log with ''
601+#
602+a
603+0
604+b
605+1
606+c
607+#
608+# Apply log with '--rewrite-db="a->c"'
609+#
610+a
611+b
612+1
613+c
614+0
615+#
616+# Apply log with '--rewrite-db="a->b"'
617+#
618+a
619+b
620+0
621+1
622+c
623+USE a;
624+DROP TABLE t1;
625+DROP DATABASE a;
626+USE b;
627+DROP TABLE t1;
628+DROP DATABASE b;
629+USE c;
630+DROP TABLE t1;
631+DROP DATABASE c;
632
633=== added file 'Percona-Server/mysql-test/t/wl36-mixed.test'
634--- Percona-Server/mysql-test/t/wl36-mixed.test 1970-01-01 00:00:00 +0000
635+++ Percona-Server/mysql-test/t/wl36-mixed.test 2012-02-09 15:07:20 +0000
636@@ -0,0 +1,3 @@
637+--source include/have_log_bin.inc
638+--source include/have_binlog_format_mixed.inc
639+--source include/wl36.inc
640
641=== added file 'Percona-Server/mysql-test/t/wl36-row.test'
642--- Percona-Server/mysql-test/t/wl36-row.test 1970-01-01 00:00:00 +0000
643+++ Percona-Server/mysql-test/t/wl36-row.test 2012-02-09 15:07:20 +0000
644@@ -0,0 +1,3 @@
645+--source include/have_log_bin.inc
646+--source include/have_binlog_format_row.inc
647+--source include/wl36.inc
648
649=== added file 'Percona-Server/mysql-test/t/wl36-statement.test'
650--- Percona-Server/mysql-test/t/wl36-statement.test 1970-01-01 00:00:00 +0000
651+++ Percona-Server/mysql-test/t/wl36-statement.test 2012-02-09 15:07:20 +0000
652@@ -0,0 +1,3 @@
653+--source include/have_log_bin.inc
654+--source include/have_binlog_format_statement.inc
655+--source include/wl36.inc
656
657=== modified file 'Percona-Server/sql/log_event.cc'
658--- Percona-Server/sql/log_event.cc 2012-01-30 04:30:33 +0000
659+++ Percona-Server/sql/log_event.cc 2012-02-09 15:07:20 +0000
660@@ -1134,7 +1134,7 @@
661 goto err;
662 }
663 if ((res= read_log_event(buf, data_len, &error, description_event)))
664- res->register_temp_buf(buf);
665+ res->register_temp_buf(buf, TRUE);
666
667 err:
668 UNLOCK_MUTEX;
669@@ -8271,6 +8271,111 @@
670 my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
671 }
672
673+
674+#ifdef MYSQL_CLIENT
675+
676+/*
677+ Rewrite database name for the event to name specified by new_db
678+ SYNOPSIS
679+ new_db Database name to change to
680+ new_len Length
681+ desc Event describing binlog that we're writing to.
682+
683+ DESCRIPTION
684+ Reset db name. This function assumes that temp_buf member contains event
685+ representation taken from a binary log. It resets m_dbnam and m_dblen and
686+ rewrites temp_buf with new db name.
687+
688+ RETURN
689+ 0 - Success
690+ other - Error
691+*/
692+
693+int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
694+ const Format_description_log_event* desc)
695+{
696+ DBUG_ENTER("Table_map_log_event::rewrite_db");
697+ DBUG_ASSERT(temp_buf);
698+
699+ uint header_len= min(desc->common_header_len,
700+ LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN;
701+ int len_diff;
702+
703+ if (!(len_diff= new_len - m_dblen))
704+ {
705+ memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1);
706+ memcpy((void*) m_dbnam, new_db, m_dblen + 1);
707+ DBUG_RETURN(0);
708+ }
709+
710+ // Create new temp_buf
711+ ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET);
712+ ulong event_new_len= event_cur_len + len_diff;
713+ char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME));
714+
715+ if (!new_temp_buf)
716+ {
717+ sql_print_error("Table_map_log_event::rewrite_db: "
718+ "failed to allocate new temp_buf (%d bytes required)",
719+ event_new_len);
720+ DBUG_RETURN(-1);
721+ }
722+
723+ // Rewrite temp_buf
724+ char* ptr= new_temp_buf;
725+ ulong cnt= 0;
726+
727+ // Copy header and change event length
728+ memcpy(ptr, temp_buf, header_len);
729+ int4store(ptr + EVENT_LEN_OFFSET, event_new_len);
730+ ptr += header_len;
731+ cnt += header_len;
732+
733+ // Write new db name length and new name
734+ *ptr++ = new_len;
735+ memcpy(ptr, new_db, new_len + 1);
736+ ptr += new_len + 1;
737+ cnt += m_dblen + 2;
738+
739+ // Copy rest part
740+ memcpy(ptr, temp_buf + cnt, event_cur_len - cnt);
741+
742+ // Reregister temp buf
743+ free_temp_buf();
744+ register_temp_buf(new_temp_buf, TRUE);
745+
746+ // Reset m_dbnam and m_dblen members
747+ m_dblen= new_len;
748+
749+ // m_dbnam resides in m_memory together with m_tblnam and m_coltype
750+ uchar* memory= m_memory;
751+ char const* tblnam= m_tblnam;
752+ uchar* coltype= m_coltype;
753+
754+ m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
755+ &m_dbnam, (uint) m_dblen + 1,
756+ &m_tblnam, (uint) m_tbllen + 1,
757+ &m_coltype, (uint) m_colcnt,
758+ NullS);
759+
760+ if (!m_memory)
761+ {
762+ sql_print_error("Table_map_log_event::rewrite_db: "
763+ "failed to allocate new m_memory (%d + %d + %d bytes required)",
764+ m_dblen + 1, m_tbllen + 1, m_colcnt);
765+ DBUG_RETURN(-1);
766+ }
767+
768+ memcpy((void*)m_dbnam, new_db, m_dblen + 1);
769+ memcpy((void*)m_tblnam, tblnam, m_tbllen + 1);
770+ memcpy(m_coltype, coltype, m_colcnt);
771+
772+ my_free(memory, MYF(MY_WME));
773+ DBUG_RETURN(0);
774+}
775+#endif /* MYSQL_CLIENT */
776+
777+
778 /*
779 Return value is an error code, one of:
780
781
782=== modified file 'Percona-Server/sql/log_event.h'
783--- Percona-Server/sql/log_event.h 2012-01-30 04:30:33 +0000
784+++ Percona-Server/sql/log_event.h 2012-02-09 15:07:20 +0000
785@@ -889,6 +889,13 @@
786 event's type, and its content is distributed in the event-specific fields.
787 */
788 char *temp_buf;
789+
790+ /*
791+ TRUE <=> this event 'owns' temp_buf and should call my_free() when done
792+ with it
793+ */
794+ bool event_owns_temp_buf;
795+
796 /*
797 Timestamp on the master(for debugging and replication of
798 NOW()/TIMESTAMP). It is important for queries and LOAD DATA
799@@ -1030,12 +1037,17 @@
800 Log_event(const char* buf, const Format_description_log_event
801 *description_event);
802 virtual ~Log_event() { free_temp_buf();}
803- void register_temp_buf(char* buf) { temp_buf = buf; }
804+ void register_temp_buf(char* buf, bool must_free)
805+ {
806+ temp_buf= buf;
807+ event_owns_temp_buf= must_free;
808+ }
809 void free_temp_buf()
810 {
811 if (temp_buf)
812 {
813- my_free(temp_buf, MYF(0));
814+ if (event_owns_temp_buf)
815+ my_free(temp_buf, MYF(0));
816 temp_buf = 0;
817 }
818 }
819@@ -3360,6 +3372,8 @@
820 ulong get_table_id() const { return m_table_id; }
821 const char *get_table_name() const { return m_tblnam; }
822 const char *get_db_name() const { return m_dbnam; }
823+ int rewrite_db(const char* new_name, size_t new_name_len,
824+ const Format_description_log_event*);
825 #endif
826
827 virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
828
829=== modified file 'Percona-Server/sql/mysql_priv.h'
830--- Percona-Server/sql/mysql_priv.h 2011-11-24 02:01:21 +0000
831+++ Percona-Server/sql/mysql_priv.h 2012-02-09 15:07:20 +0000
832@@ -93,12 +93,16 @@
833 #include "unireg.h"
834
835 void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
836+#endif // MYSQL_CLIENT
837+
838 void *sql_alloc(size_t);
839 void *sql_calloc(size_t);
840 char *sql_strdup(const char *str);
841 char *sql_strmake(const char *str, size_t len);
842 void *sql_memdup(const void * ptr, size_t size);
843 void sql_element_free(void *ptr);
844+
845+#ifndef MYSQL_CLIENT
846 char *sql_strmake_with_convert(const char *str, size_t arg_length,
847 CHARSET_INFO *from_cs,
848 size_t max_res_length,
849
850=== modified file 'Percona-Server/sql/mysqld.cc'
851--- Percona-Server/sql/mysqld.cc 2012-02-07 03:25:46 +0000
852+++ Percona-Server/sql/mysqld.cc 2012-02-09 15:07:20 +0000
853@@ -8469,6 +8469,7 @@
854 }
855 case (int)OPT_REPLICATE_REWRITE_DB:
856 {
857+ /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */
858 char* key = argument,*p, *val;
859
860 if (!(p= strstr(argument, "->")))
861
862=== modified file 'Percona-Server/sql/rpl_filter.cc'
863--- Percona-Server/sql/rpl_filter.cc 2011-06-30 15:37:13 +0000
864+++ Percona-Server/sql/rpl_filter.cc 2012-02-09 15:07:20 +0000
865@@ -48,6 +48,7 @@
866 }
867
868
869+#ifndef MYSQL_CLIENT
870 /*
871 Returns true if table should be logged/replicated
872
873@@ -132,6 +133,7 @@
874 !do_table_inited && !wild_do_table_inited);
875 }
876
877+#endif
878
879 /*
880 Checks whether a db matches some do_db and ignore_db rules
881@@ -517,6 +519,13 @@
882 }
883
884
885+bool
886+Rpl_filter::rewrite_db_is_empty()
887+{
888+ return rewrite_db.is_empty();
889+}
890+
891+
892 const char*
893 Rpl_filter::get_rewrite_db(const char* db, size_t *new_len)
894 {
895
896=== modified file 'Percona-Server/sql/rpl_filter.h'
897--- Percona-Server/sql/rpl_filter.h 2007-05-10 09:59:39 +0000
898+++ Percona-Server/sql/rpl_filter.h 2012-02-09 15:07:20 +0000
899@@ -42,7 +42,9 @@
900
901 /* Checks - returns true if ok to replicate/log */
902
903- bool tables_ok(const char* db, TABLE_LIST* tables);
904+#ifndef MYSQL_CLIENT
905+ bool tables_ok(const char* db, TABLE_LIST *tables);
906+#endif
907 bool db_ok(const char* db);
908 bool db_ok_with_wild_table(const char *db);
909
910@@ -69,6 +71,7 @@
911 void get_wild_do_table(String* str);
912 void get_wild_ignore_table(String* str);
913
914+ bool rewrite_db_is_empty();
915 const char* get_rewrite_db(const char* db, size_t *new_len);
916
917 I_List<i_string>* get_do_db();
918
919=== modified file 'Percona-Server/sql/sql_string.cc'
920--- Percona-Server/sql/sql_string.cc 2011-10-31 09:10:04 +0000
921+++ Percona-Server/sql/sql_string.cc 2012-02-09 15:07:20 +0000
922@@ -39,6 +39,9 @@
923
924 #include "sql_string.h"
925
926+#ifdef MYSQL_CLIENT
927+#error Attempt to use server-side sql_string on client. Use client/sql_string.cc
928+#endif
929 /*****************************************************************************
930 ** String functions
931 *****************************************************************************/
932
933=== modified file 'Percona-Server/sql/sql_string.h'
934--- Percona-Server/sql/sql_string.h 2011-07-03 15:47:37 +0000
935+++ Percona-Server/sql/sql_string.h 2012-02-09 15:07:20 +0000
936@@ -1,3 +1,6 @@
937+#ifndef MYSQL_SQL_STRING_H_INCLUDED
938+#define MYSQL_SQL_STRING_H_INCLUDED
939+
940 /*
941 Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
942
943@@ -25,6 +28,10 @@
944 #define NOT_FIXED_DEC 31
945 #endif
946
947+#ifdef MYSQL_CLIENT
948+#error Attempt to use server-side sql_string on client. Use client/sql_string.h
949+#endif
950+
951 class String;
952 int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
953 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
954@@ -408,3 +415,5 @@
955 {
956 return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
957 }
958+
959+#endif // MYSQL_SQL_STRING_H_INCLUDED
960
961=== modified file 'Percona-Server/sql/thr_malloc.cc'
962--- Percona-Server/sql/thr_malloc.cc 2011-06-30 15:37:13 +0000
963+++ Percona-Server/sql/thr_malloc.cc 2012-02-09 15:07:20 +0000
964@@ -65,11 +65,13 @@
965 }
966
967
968+#ifndef MYSQL_CLIENT
969 void *sql_alloc(size_t Size)
970 {
971 MEM_ROOT *root= *my_pthread_getspecific_ptr(MEM_ROOT**,THR_MALLOC);
972 return alloc_root(root,Size);
973 }
974+#endif
975
976
977 void *sql_calloc(size_t size)
978
979=== added file 'doc/source/flexibility/mysqlbinlog_change_db.rst'
980--- doc/source/flexibility/mysqlbinlog_change_db.rst 1970-01-01 00:00:00 +0000
981+++ doc/source/flexibility/mysqlbinlog_change_db.rst 2012-02-09 15:07:20 +0000
982@@ -0,0 +1,43 @@
983+.. _mysqlbinlog_change_db:
984+
985+=========================
986+Ability to change database for mysqlbinlog
987+=========================
988+
989+Sometimes there is a need to take a binary log and apply it to a database with
990+a different name than the original name of the database on binlog producer.
991+
992+If one is using statement-based replication, he can achieve this by grepping
993+out "USE dbname" statements out of the output of mysqlbinlog(*). With
994+row-based replication this is no longer possible, as database name is encoded
995+within the the BINLOG '....' statement.
996+
997+This task is about adding an option to mysqlbinlog that would allow to change
998+the names of used databases in both RBR and SBR events.
999+
1000+Varible :variable:`rewrite-db` of **mysqlbinlog** utility allows to setup rewriting rule "from->"to".
1001+
1002+Version Specific Information
1003+============================
1004+
1005+ * 5.1.62-12.1
1006+ Full functionality.
1007+
1008+Client Command Line Parameter
1009+=============================
1010+
1011+.. variable:: rewrite-db
1012+
1013+ :cli: Yes
1014+ :conf: Yes
1015+ :scope: Global
1016+ :dyn: No
1017+ :vartype: String
1018+ :default: Off
1019+
1020+
1021+Related Reading
1022+===============
1023+
1024+ * `WL #36 <http://askmonty.org/worklog/Server-Sprint/?tid=36>`_
1025+
1026
1027=== modified file 'doc/source/index.rst'
1028--- doc/source/index.rst 2012-01-31 10:35:01 +0000
1029+++ doc/source/index.rst 2012-02-09 15:07:20 +0000
1030@@ -88,6 +88,7 @@
1031 flexibility/innodb_files_extend
1032 flexibility/log_warnings_suppress
1033 flexibility/mysql_remove_eol_carret
1034+ flexibility/mysqlbinlog_change_db
1035 flexibility/replication_skip_single_statement
1036 flexibility/buff_read_ahead_area
1037 flexibility/innodb_fast_shutdown

Subscribers

People subscribed via source and target branches