Merge lp:~vlad-lesin/percona-server/5.5-mysqlbinlog-replacedb into lp:percona-server/5.5
- 5.5-mysqlbinlog-replacedb
- Merge into 5.5
Status: | Merged |
---|---|
Approved by: | Laurynas Biveinis |
Approved revision: | no longer in the source branch. |
Merged at revision: | 629 |
Proposed branch: | lp:~vlad-lesin/percona-server/5.5-mysqlbinlog-replacedb |
Merge into: | lp:percona-server/5.5 |
Diff against target: |
1027 lines (+858/-4) (has conflicts) 15 files modified
client/CMakeLists.txt (+6/-0) client/client_priv.h (+1/-0) client/mysqlbinlog.cc (+164/-3) mysql-test/extra/rpl_tests/grep_pattern.inc (+22/-0) mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result (+33/-0) mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result (+29/-0) mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result (+29/-0) mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result (+152/-0) mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test (+95/-0) mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test (+79/-0) mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test (+61/-0) mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt (+1/-0) mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test (+80/-0) sql/log_event.cc (+102/-0) sql/log_event.h (+4/-1) Text conflict in client/CMakeLists.txt |
To merge this branch: | bzr merge lp:~vlad-lesin/percona-server/5.5-mysqlbinlog-replacedb |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Stewart Smith (community) | Needs Fixing | ||
George Ormond Lorch III (community) | g2 | Approve | |
Review via email: mp+196578@code.launchpad.net |
Commit message
Description of the change
Port --rewrite-db mysqlbinlog option from 5.1.
--rewrite-db is a string option which allows to replace one db-name to another
in mysqlbinlog output. The format of the string value is the following:
"from1-
the correspondent "from[123]" names must be replaced.
The original implementation does not replace db names in statements for
statement-based binlog, it just replaces db name of binlog event and issues
"USE" statement with replaced db name if necessary. I think this restriction
concerned with unwillingness to implement complex logic for parsing db names
from statements for such simple feature.
But for row-based binlog it replaces db names in statements correctly because
each table name is mapped to some number in binlog and it is quite easy to
extract such table ids from binlog event and replace one name by another.
http://
George Ormond Lorch III (gl-az) : | # |
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
- This needs two associated blueprints, one for 5.5, and one for
5.6
- Oracle has implemented this functionality in 5.7.1. From the
user perspective the difference is option syntax, ours:
-
theirs:
-
To ensure smooth migration once we switch to their
implement
testcase.
- What should be the interaction between --rewrite-db and
--database options, i.e. which one should come first? My first
thought is rewrite-db before database, i.e. first we map, and
then we filter. This is what the current patch appears to do
for SBR, but it's reversed for RBR (judging from
shall_
also need a testcase.
- Rewrite rules are not applied to CREATE_FILE_EVENT. This
wouldn't be an issue in itself, but these events are filtered
against --database, thus, depending on how the previous item is
resolved, these events might need rewrite-db application too,
so that they can be filtered properly. This would also need a
testcase.
- LOAD DATA events (EXECUTE_
too. Probably this can be handled together with the previous
item.
- Because RBR event DB rewrite requires shifting of
Table_
changes, please test this case for both shorter and longer
names.
- Since Oracle has implemented this, there are some Oracle
testcases too. Consider importing binlog_
binlog_
5.7. If you choose to, make sure they get the correct bzr file
ids (i.e. bzr add --file-
Stewart Smith (stewart) wrote : | # |
Laurynas Biveinis <email address hidden> writes:
> - Oracle has implemented this functionality in 5.7.1. From the
> user perspective the difference is option syntax, ours:
> --rewrite-
> theirs:
> --rewrite-db='a->b' --rewrite-db='c->d'
> To ensure smooth migration once we switch to their
> implementation in 5.7, please test both syntaxes in the
> testcase.
We should probably throw a warning if the user uses the syntax that will
break in 5.7, as really we should just take the Oracle impl in 5.7.
--
Stewart Smith
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
> Laurynas Biveinis <email address hidden> writes:
> > - Oracle has implemented this functionality in 5.7.1. From the
> > user perspective the difference is option syntax, ours:
> > --rewrite-
> > theirs:
> > --rewrite-db='a->b' --rewrite-db='c->d'
> > To ensure smooth migration once we switch to their
> > implementation in 5.7, please test both syntaxes in the
> > testcase.
>
> We should probably throw a warning if the user uses the syntax that will
> break in 5.7, as really we should just take the Oracle impl in 5.7.
>
>
> --
> Stewart Smith
We can also (if the customer does not object) take the 5.7 syntax in 5.5 already for a bit simpler code/testcases.
Vlad Lesin (vlad-lesin) wrote : | # |
On 12/20/2013 12:58 PM, Laurynas Biveinis wrote:
> - This needs two associated blueprints, one for 5.5, and one for
> 5.6
Done.
> - Oracle has implemented this functionality in 5.7.1. From the
> user perspective the difference is option syntax, ours:
> --rewrite-
> theirs:
> --rewrite-db='a->b' --rewrite-db='c->d'
> To ensure smooth migration once we switch to their
> implementation in 5.7, please test both syntaxes in the
> testcase.
Yes, currently both formats are allowed, but if the old
format(
> - What should be the interaction between --rewrite-db and
> --database options, i.e. which one should come first? My first
> thought is rewrite-db before database, i.e. first we map, and
> then we filter. This is what the current patch appears to do
> for SBR, but it's reversed for RBR (judging from
> shall_skip_
> also need a testcase.
Yes, you are right, the order of rewrite-db and database filtering was
reversed for RBR. Fixed and the corresponding test is added.
> - Rewrite rules are not applied to CREATE_FILE_EVENT. This
> wouldn't be an issue in itself, but these events are filtered
> against --database, thus, depending on how the previous item is
> resolved, these events might need rewrite-db application too,
> so that they can be filtered properly. This would also need a
> testcase.
I added the code which replaces db name in the event processing, but I
have no idea how to test it as there is the following comment in
log_event.h:
"The events which really update data are Query_log_event,
Execute_
Execute_
Begin_load_query and Append_block events to replicate LOAD DATA INFILE.
Create_
were used to replicate LOAD DATA before the 5.0.3)."
So CREATE_FILE_EVENT were used before 5.0.3.
> - LOAD DATA events (EXECUTE_
> too. Probably this can be handled together with the previous
> item.
The corresponding test case is made.
> - Because RBR event DB rewrite requires shifting of
> Table_map_og_event contents around if the DB name length
> changes, please test this case for both shorter and longer
> names.
Done.
> - Since Oracle has implemented this, there are some Oracle
> testcases too. Consider importing binlog_
> binlog_
> 5.7. If you choose to, make sure they get the correct bzr file
> ids (i.e. bzr add --file-
Done.
Vlad Lesin (vlad-lesin) wrote : | # |
Jenkins testing results: http://
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
> > - Rewrite rules are not applied to CREATE_FILE_EVENT. This
> > wouldn't be an issue in itself, but these events are filtered
> > against --database, thus, depending on how the previous item is
> > resolved, these events might need rewrite-db application too,
> > so that they can be filtered properly. This would also need a
> > testcase.
> I added the code which replaces db name in the event processing, but I
> have no idea how to test it as there is the following comment in
> log_event.h:
>
> "The events which really update data are Query_log_event,
> Execute_
> Execute_
> Begin_load_query and Append_block events to replicate LOAD DATA INFILE.
> Create_
> were used to replicate LOAD DATA before the 5.0.3)."
>
> So CREATE_FILE_EVENT were used before 5.0.3.
Ah sorry I missed this, this is a non-issue then.
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
- The warning for "a->b,c->d" syntax seems to be repeated for
each comma, so "a->b,c->d,e->f" would print the warning twice,
which is unnecessary.
- Does running our testcases on MySQL 5.7 give the expected
results?
Vlad Lesin (vlad-lesin) wrote : | # |
> - The warning for "a->b,c->d" syntax seems to be repeated for
> each comma, so "a->b,c->d,e->f" would print the warning twice,
> which is unnecessary.
Fixed.
> - Does running our testcases on MySQL 5.7 give the expected
> results?
No because 5.7 does not support our syntax.
http://
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
> > - The warning for "a->b,c->d" syntax seems to be repeated for
> > each comma, so "a->b,c->d,e->f" would print the warning twice,
> > which is unnecessary.
> Fixed.
What was the fix?
The relevant code reads
if (*ptr == ',')
{
warning("The comma-separated list of rewritings syntax is obsolete and is discarded in 5.7\n");
*(ptr++)= 0;
}
In order to warn only once for e.g. --rewrite-
Or am I missing something here?
If you need to repush, then also please fix indentation at diff lines 216, 220, 227, 231, and curly brace not having own line at 217.
> > - Does running our testcases on MySQL 5.7 give the expected
> > results?
> No because 5.7 does not support our syntax.
Right, but accounted for syntax changes? Does our and their order of applying --database= --rewrite-db= agree?
Vlad Lesin (vlad-lesin) wrote : | # |
> > > - The warning for "a->b,c->d" syntax seems to be repeated for
> > > each comma, so "a->b,c->d,e->f" would print the warning twice,
> > > which is unnecessary.
> > Fixed.
>
> What was the fix?
...
> Or am I missing something here?
Yes, you are right, I was sure I fixed it. But somehow I did not. I believe it is fixed now.
> > > - Does running our testcases on MySQL 5.7 give the expected
> > > results?
> > No because 5.7 does not support our syntax.
>
> Right, but accounted for syntax changes? Does our and their order of applying
> --database= --rewrite-db= agree?
Yes. For 5.7 dump_local_
As well I have rebased the code to the newest 5.5. Here id jenkins testing: http://
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
> > > > - The warning for "a->b,c->d" syntax seems to be repeated for
> > > > each comma, so "a->b,c->d,e->f" would print the warning twice,
> > > > which is unnecessary.
> > > Fixed.
> >
> > What was the fix?
> ...
> > Or am I missing something here?
>
> Yes, you are right, I was sure I fixed it. But somehow I did not. I believe it
> is fixed now.
The flag is local to OPT_REWRITE_DB, so --rewrite-
> As well I have rebased the code to the newest 5.5.
Uhm, why? This is not a GCA branch anymore then?
Vlad Lesin (vlad-lesin) wrote : | # |
> The flag is local to OPT_REWRITE_DB, so --rewrite-
> --rewrite-
> it?
Yep. Fixed.
> > As well I have rebased the code to the newest 5.5.
> Uhm, why? This is not a GCA branch anymore then?
To make merging to trunk a little bit easier. The structure of trunk source tree was changed and there were a couple of conflicts due to some code change which was resolved manually.
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
As discussed on IRC, this will need a GCA rebase.
Vlad Lesin (vlad-lesin) wrote : | # |
> As discussed on IRC, this will need a GCA rebase.
Rebased.
Laurynas Biveinis (laurynas-biveinis) : | # |
Preview Diff
1 | === modified file 'client/CMakeLists.txt' | |||
2 | --- client/CMakeLists.txt 2013-07-23 04:41:43 +0000 | |||
3 | +++ client/CMakeLists.txt 2014-02-15 00:33:28 +0000 | |||
4 | @@ -57,8 +57,14 @@ | |||
5 | 57 | MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c) | 57 | MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c) |
6 | 58 | TARGET_LINK_LIBRARIES(mysql_plugin perconaserverclient) | 58 | TARGET_LINK_LIBRARIES(mysql_plugin perconaserverclient) |
7 | 59 | 59 | ||
8 | 60 | <<<<<<< TREE | ||
9 | 60 | MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc sql_string.cc) | 61 | MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc sql_string.cc) |
10 | 61 | TARGET_LINK_LIBRARIES(mysqlbinlog perconaserverclient) | 62 | TARGET_LINK_LIBRARIES(mysqlbinlog perconaserverclient) |
11 | 63 | ======= | ||
12 | 64 | MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc sql_string.cc | ||
13 | 65 | ../sql/rpl_filter.cc ../sql/sql_list.cc) | ||
14 | 66 | TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient) | ||
15 | 67 | >>>>>>> MERGE-SOURCE | ||
16 | 62 | 68 | ||
17 | 63 | MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc) | 69 | MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc) |
18 | 64 | TARGET_LINK_LIBRARIES(mysqladmin perconaserverclient) | 70 | TARGET_LINK_LIBRARIES(mysqladmin perconaserverclient) |
19 | 65 | 71 | ||
20 | === modified file 'client/client_priv.h' | |||
21 | --- client/client_priv.h 2013-05-15 05:05:18 +0000 | |||
22 | +++ client/client_priv.h 2014-02-15 00:33:28 +0000 | |||
23 | @@ -94,6 +94,7 @@ | |||
24 | 94 | OPT_DEFAULT_PLUGIN, | 94 | OPT_DEFAULT_PLUGIN, |
25 | 95 | OPT_ENABLE_CLEARTEXT_PLUGIN, | 95 | OPT_ENABLE_CLEARTEXT_PLUGIN, |
26 | 96 | OPT_INNODB_OPTIMIZE_KEYS, | 96 | OPT_INNODB_OPTIMIZE_KEYS, |
27 | 97 | OPT_REWRITE_DB, | ||
28 | 97 | OPT_MAX_CLIENT_OPTION | 98 | OPT_MAX_CLIENT_OPTION |
29 | 98 | }; | 99 | }; |
30 | 99 | 100 | ||
31 | 100 | 101 | ||
32 | === modified file 'client/mysqlbinlog.cc' | |||
33 | --- client/mysqlbinlog.cc 2013-10-31 18:24:55 +0000 | |||
34 | +++ client/mysqlbinlog.cc 2014-02-15 00:33:28 +0000 | |||
35 | @@ -39,6 +39,18 @@ | |||
36 | 39 | #include "my_dir.h" | 39 | #include "my_dir.h" |
37 | 40 | #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE | 40 | #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE |
38 | 41 | 41 | ||
39 | 42 | /* Needed for Rpl_filter */ | ||
40 | 43 | CHARSET_INFO* system_charset_info= &my_charset_utf8_general_ci; | ||
41 | 44 | |||
42 | 45 | #include "rpl_filter.h" | ||
43 | 46 | |||
44 | 47 | /* | ||
45 | 48 | True if obsolette syntax warning has been already shown | ||
46 | 49 | during parsing --rewrite-db command line option | ||
47 | 50 | */ | ||
48 | 51 | bool rewrite_db_obs_syn_warn= false; | ||
49 | 52 | Rpl_filter *binlog_filter= NULL; | ||
50 | 53 | |||
51 | 42 | #define BIN_LOG_HEADER_SIZE 4 | 54 | #define BIN_LOG_HEADER_SIZE 4 |
52 | 43 | #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) | 55 | #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) |
53 | 44 | 56 | ||
54 | @@ -631,6 +643,35 @@ | |||
55 | 631 | strcmp(log_dbname, database); | 643 | strcmp(log_dbname, database); |
56 | 632 | } | 644 | } |
57 | 633 | 645 | ||
58 | 646 | /** | ||
59 | 647 | Rewrites db name in T instance if binlog_filter contains | ||
60 | 648 | name for replacement(see --rewrite-db option). | ||
61 | 649 | |||
62 | 650 | T::db must be weak pointer and can point to the memory owned by | ||
63 | 651 | "binlog_filter" after this function execution, that is why "ev" must be | ||
64 | 652 | destroyed before "binlog_filter". | ||
65 | 653 | |||
66 | 654 | @param ev Event to process | ||
67 | 655 | */ | ||
68 | 656 | template <typename T> | ||
69 | 657 | static void rewrite_db(T &ev) | ||
70 | 658 | { | ||
71 | 659 | size_t len_to= 0; | ||
72 | 660 | const char* db_to; | ||
73 | 661 | |||
74 | 662 | DBUG_ASSERT(binlog_filter); | ||
75 | 663 | |||
76 | 664 | if (!ev.db) | ||
77 | 665 | return; | ||
78 | 666 | |||
79 | 667 | db_to= binlog_filter->get_rewrite_db(ev.db, &len_to); | ||
80 | 668 | |||
81 | 669 | if (!len_to) | ||
82 | 670 | return; | ||
83 | 671 | |||
84 | 672 | ev.db= db_to; | ||
85 | 673 | ev.db_len= len_to; | ||
86 | 674 | } | ||
87 | 634 | 675 | ||
88 | 635 | /** | 676 | /** |
89 | 636 | Prints the given event in base64 format. | 677 | Prints the given event in base64 format. |
90 | @@ -752,8 +793,16 @@ | |||
91 | 752 | 793 | ||
92 | 753 | switch (ev_type) { | 794 | switch (ev_type) { |
93 | 754 | case QUERY_EVENT: | 795 | case QUERY_EVENT: |
96 | 755 | if (!((Query_log_event*)ev)->is_trans_keyword() && | 796 | { |
97 | 756 | shall_skip_database(((Query_log_event*)ev)->db)) | 797 | Query_log_event *qlev = static_cast<Query_log_event *>(ev); |
98 | 798 | /* | ||
99 | 799 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
100 | 800 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
101 | 801 | */ | ||
102 | 802 | if (binlog_filter) | ||
103 | 803 | rewrite_db(*qlev); | ||
104 | 804 | if (!qlev->is_trans_keyword() && | ||
105 | 805 | shall_skip_database(qlev->db)) | ||
106 | 757 | goto end; | 806 | goto end; |
107 | 758 | if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) | 807 | if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) |
108 | 759 | { | 808 | { |
109 | @@ -767,11 +816,17 @@ | |||
110 | 767 | if (head->error == -1) | 816 | if (head->error == -1) |
111 | 768 | goto err; | 817 | goto err; |
112 | 769 | break; | 818 | break; |
114 | 770 | 819 | } | |
115 | 771 | case CREATE_FILE_EVENT: | 820 | case CREATE_FILE_EVENT: |
116 | 772 | { | 821 | { |
117 | 773 | Create_file_log_event* ce= (Create_file_log_event*)ev; | 822 | Create_file_log_event* ce= (Create_file_log_event*)ev; |
118 | 774 | /* | 823 | /* |
119 | 824 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
120 | 825 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
121 | 826 | */ | ||
122 | 827 | if (binlog_filter) | ||
123 | 828 | rewrite_db(*ce); | ||
124 | 829 | /* | ||
125 | 775 | We test if this event has to be ignored. If yes, we don't save | 830 | We test if this event has to be ignored. If yes, we don't save |
126 | 776 | this event; this will have the good side-effect of ignoring all | 831 | this event; this will have the good side-effect of ignoring all |
127 | 777 | related Append_block and Exec_load. | 832 | related Append_block and Exec_load. |
128 | @@ -903,6 +958,12 @@ | |||
129 | 903 | case EXECUTE_LOAD_QUERY_EVENT: | 958 | case EXECUTE_LOAD_QUERY_EVENT: |
130 | 904 | { | 959 | { |
131 | 905 | Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; | 960 | Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; |
132 | 961 | /* | ||
133 | 962 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
134 | 963 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
135 | 964 | */ | ||
136 | 965 | if (binlog_filter) | ||
137 | 966 | rewrite_db(*exlq); | ||
138 | 906 | char *fname= load_processor.grab_fname(exlq->file_id); | 967 | char *fname= load_processor.grab_fname(exlq->file_id); |
139 | 907 | 968 | ||
140 | 908 | if (!shall_skip_database(exlq->db)) | 969 | if (!shall_skip_database(exlq->db)) |
141 | @@ -930,6 +991,19 @@ | |||
142 | 930 | case TABLE_MAP_EVENT: | 991 | case TABLE_MAP_EVENT: |
143 | 931 | { | 992 | { |
144 | 932 | Table_map_log_event *map= ((Table_map_log_event *)ev); | 993 | Table_map_log_event *map= ((Table_map_log_event *)ev); |
145 | 994 | // Rewrite db name here (see --rewrite-db option) | ||
146 | 995 | if (binlog_filter) | ||
147 | 996 | { | ||
148 | 997 | size_t len_to= 0; | ||
149 | 998 | const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), | ||
150 | 999 | &len_to); | ||
151 | 1000 | if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) | ||
152 | 1001 | { | ||
153 | 1002 | error("Could not rewrite database name"); | ||
154 | 1003 | goto err; | ||
155 | 1004 | } | ||
156 | 1005 | } | ||
157 | 1006 | |||
158 | 933 | if (shall_skip_database(map->get_db_name())) | 1007 | if (shall_skip_database(map->get_db_name())) |
159 | 934 | { | 1008 | { |
160 | 935 | print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map); | 1009 | print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map); |
161 | @@ -1225,6 +1299,10 @@ | |||
162 | 1225 | "Used to reserve file descriptors for use by this program.", | 1299 | "Used to reserve file descriptors for use by this program.", |
163 | 1226 | &open_files_limit, &open_files_limit, 0, GET_ULONG, | 1300 | &open_files_limit, &open_files_limit, 0, GET_ULONG, |
164 | 1227 | REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, | 1301 | REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, |
165 | 1302 | {"rewrite-db", OPT_REWRITE_DB, | ||
166 | 1303 | "Updates to a database with a different name than the original. " | ||
167 | 1304 | "Example: rewrite-db='from->to'.", | ||
168 | 1305 | 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
169 | 1228 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} | 1306 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
170 | 1229 | }; | 1307 | }; |
171 | 1230 | 1308 | ||
172 | @@ -1303,6 +1381,7 @@ | |||
173 | 1303 | my_free(dirname_for_local_load); | 1381 | my_free(dirname_for_local_load); |
174 | 1304 | 1382 | ||
175 | 1305 | delete glob_description_event; | 1383 | delete glob_description_event; |
176 | 1384 | delete binlog_filter; | ||
177 | 1306 | if (mysql) | 1385 | if (mysql) |
178 | 1307 | mysql_close(mysql); | 1386 | mysql_close(mysql); |
179 | 1308 | } | 1387 | } |
180 | @@ -1406,6 +1485,88 @@ | |||
181 | 1406 | (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); | 1485 | (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); |
182 | 1407 | } | 1486 | } |
183 | 1408 | break; | 1487 | break; |
184 | 1488 | case OPT_REWRITE_DB: // db_from->db_to | ||
185 | 1489 | { | ||
186 | 1490 | /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ | ||
187 | 1491 | char* ptr= argument; | ||
188 | 1492 | do { | ||
189 | 1493 | char* key= ptr; // db-from | ||
190 | 1494 | char* val; // db-to | ||
191 | 1495 | |||
192 | 1496 | // Where key begins | ||
193 | 1497 | while (*key && my_isspace(&my_charset_latin1, *key)) | ||
194 | 1498 | key++; | ||
195 | 1499 | |||
196 | 1500 | // Where val begins | ||
197 | 1501 | if (!(ptr= strstr(key, "->"))) | ||
198 | 1502 | { | ||
199 | 1503 | sql_print_error("Bad syntax in rewrite-db: missing '->'!\n"); | ||
200 | 1504 | return 1; | ||
201 | 1505 | } | ||
202 | 1506 | val= ptr + 2; | ||
203 | 1507 | while (*val && my_isspace(&my_charset_latin1, *val)) | ||
204 | 1508 | val++; | ||
205 | 1509 | |||
206 | 1510 | // Write \0 and skip blanks at the end of key | ||
207 | 1511 | *ptr-- = 0; | ||
208 | 1512 | while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument) | ||
209 | 1513 | *ptr-- = 0; | ||
210 | 1514 | |||
211 | 1515 | if (!*key) | ||
212 | 1516 | { | ||
213 | 1517 | sql_print_error("Bad syntax in rewrite-db: empty db-from!\n"); | ||
214 | 1518 | return 1; | ||
215 | 1519 | } | ||
216 | 1520 | |||
217 | 1521 | // Skip blanks at the end of val | ||
218 | 1522 | ptr= val; | ||
219 | 1523 | while (*ptr && !my_isspace(&my_charset_latin1, *ptr) && *ptr != ',') | ||
220 | 1524 | ++ptr; | ||
221 | 1525 | |||
222 | 1526 | if (my_isspace(&my_charset_latin1, *ptr)) | ||
223 | 1527 | { | ||
224 | 1528 | *(ptr++)= 0; | ||
225 | 1529 | while (*ptr && *ptr != ',') | ||
226 | 1530 | { | ||
227 | 1531 | if (!my_isspace(&my_charset_latin1, *ptr)) { | ||
228 | 1532 | sql_print_error("Bad syntax in rewrite-db: db-to must contain db " | ||
229 | 1533 | "name without spaces!\n"); | ||
230 | 1534 | return 1; | ||
231 | 1535 | } | ||
232 | 1536 | ++ptr; | ||
233 | 1537 | } | ||
234 | 1538 | } | ||
235 | 1539 | |||
236 | 1540 | if (*ptr == ',') | ||
237 | 1541 | { | ||
238 | 1542 | if (!rewrite_db_obs_syn_warn) | ||
239 | 1543 | { | ||
240 | 1544 | warning("The comma-separated list of rewritings syntax is obsolete and " | ||
241 | 1545 | "discarded in 5.7\n"); | ||
242 | 1546 | rewrite_db_obs_syn_warn= true; | ||
243 | 1547 | } | ||
244 | 1548 | *(ptr++)= 0; | ||
245 | 1549 | } | ||
246 | 1550 | else | ||
247 | 1551 | *ptr= 0; | ||
248 | 1552 | |||
249 | 1553 | if (!*val) | ||
250 | 1554 | { | ||
251 | 1555 | sql_print_error("Bad syntax in rewrite-db: empty db-to!\n"); | ||
252 | 1556 | return 1; | ||
253 | 1557 | } | ||
254 | 1558 | |||
255 | 1559 | if (!binlog_filter && | ||
256 | 1560 | !(binlog_filter= new Rpl_filter)) | ||
257 | 1561 | { | ||
258 | 1562 | sql_print_error("Failed to create Rpl_filter\n"); | ||
259 | 1563 | return 1; | ||
260 | 1564 | } | ||
261 | 1565 | |||
262 | 1566 | binlog_filter->add_db_rewrite(key, val); | ||
263 | 1567 | } while (*ptr); | ||
264 | 1568 | break; | ||
265 | 1569 | } | ||
266 | 1409 | case 'v': | 1570 | case 'v': |
267 | 1410 | if (argument == disabled_my_option) | 1571 | if (argument == disabled_my_option) |
268 | 1411 | verbose= 0; | 1572 | verbose= 0; |
269 | 1412 | 1573 | ||
270 | === added file 'mysql-test/extra/rpl_tests/grep_pattern.inc' | |||
271 | --- mysql-test/extra/rpl_tests/grep_pattern.inc 1970-01-01 00:00:00 +0000 | |||
272 | +++ mysql-test/extra/rpl_tests/grep_pattern.inc 2014-02-15 00:33:28 +0000 | |||
273 | @@ -0,0 +1,22 @@ | |||
274 | 1 | # Please set GREP_FILE and GREP_PATTERN environment variables | ||
275 | 2 | # to work this file properly. | ||
276 | 3 | --perl | ||
277 | 4 | use strict; | ||
278 | 5 | my $file= $ENV{'GREP_FILE'} or die "grep file not set"; | ||
279 | 6 | my $pattern= $ENV{'GREP_PATTERN'} or die "pattern is not set"; | ||
280 | 7 | open(FILE, "$file") or die("Unable to open $file: $!\n"); | ||
281 | 8 | my $count = 0; | ||
282 | 9 | print "Matching lines are:\n"; | ||
283 | 10 | while (<FILE>) { | ||
284 | 11 | my $line = $_; | ||
285 | 12 | if ($line =~ /$pattern/) { | ||
286 | 13 | print "$line\n"; | ||
287 | 14 | $count++; | ||
288 | 15 | } | ||
289 | 16 | } | ||
290 | 17 | if ($count == 0) { | ||
291 | 18 | print "None\n"; | ||
292 | 19 | } | ||
293 | 20 | print "Occurrences of the $pattern in the input file : $count\n"; | ||
294 | 21 | close(FILE); | ||
295 | 22 | EOF | ||
296 | 0 | 23 | ||
297 | === added file 'mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result' | |||
298 | --- mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result 1970-01-01 00:00:00 +0000 | |||
299 | +++ mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result 2014-02-15 00:33:28 +0000 | |||
300 | @@ -0,0 +1,33 @@ | |||
301 | 1 | RESET MASTER; | ||
302 | 2 | CREATE DATABASE db1; | ||
303 | 3 | USE db1; | ||
304 | 4 | CREATE TABLE t1 (i INT); | ||
305 | 5 | INSERT INTO t1 VALUES(1); | ||
306 | 6 | INSERT INTO t1 VALUES(2); | ||
307 | 7 | UPDATE t1 SET i= i+1; | ||
308 | 8 | DELETE FROM t1 WHERE i=2; | ||
309 | 9 | [Syntax error in the use of the new option: The from database name is missing] | ||
310 | 10 | [Syntax error in the use of the new option: The '->' is missing] | ||
311 | 11 | [Syntax error in the use of the new option: The to database name is missing] | ||
312 | 12 | [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 1] | ||
313 | 13 | [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4,db5->db6"] | ||
314 | 14 | [log_grep.inc] file: mysqltest.log pattern: The comma-separated list of rewritings syntax is obsolete and discarded | ||
315 | 15 | [log_grep.inc] lines: 1 | ||
316 | 16 | [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 2] | ||
317 | 17 | [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4" --rewrite-db="db5->db6,db6->db7"] | ||
318 | 18 | [log_grep.inc] file: mysqltest.log pattern: The comma-separated list of rewritings syntax is obsolete and discarded | ||
319 | 19 | [log_grep.inc] lines: 2 | ||
320 | 20 | [VALID SYNTAX,The from->to database names are correctly mentioned] | ||
321 | 21 | #Dropping the database db1 and creating the table in the new database db2. | ||
322 | 22 | CREATE DATABASE db2; | ||
323 | 23 | DROP DATABASE db1; | ||
324 | 24 | RESET MASTER; | ||
325 | 25 | SELECT * FROM db2.t1; | ||
326 | 26 | ERROR 42S02: Table 'db2.t1' doesn't exist | ||
327 | 27 | DROP DATABASE db1; | ||
328 | 28 | RESET MASTER; | ||
329 | 29 | [The event of table db1.t1 has been successfully applied to db2.t1] | ||
330 | 30 | include/assert.inc [Assert that table db2.t1 has one row after applying the sql file.] | ||
331 | 31 | CLEANUP | ||
332 | 32 | DROP DATABASE db1; | ||
333 | 33 | DROP DATABASE db2; | ||
334 | 0 | 34 | ||
335 | === added file 'mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result' | |||
336 | --- mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result 1970-01-01 00:00:00 +0000 | |||
337 | +++ mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result 2014-02-15 00:33:28 +0000 | |||
338 | @@ -0,0 +1,29 @@ | |||
339 | 1 | RESET MASTER; | ||
340 | 2 | CREATE DATABASE db1; | ||
341 | 3 | USE db1; | ||
342 | 4 | CREATE TABLE t1 (i INT); | ||
343 | 5 | INSERT INTO db1.t1 VALUES(1); | ||
344 | 6 | INSERT INTO db1.t1 VALUES(2); | ||
345 | 7 | UPDATE t1 SET i= i+1; | ||
346 | 8 | DELETE FROM t1 WHERE i=2; | ||
347 | 9 | CREATE DATABASE db2; | ||
348 | 10 | CREATE TABLE db2.t1 (i INT); | ||
349 | 11 | INSERT INTO db2.t1 VALUES(3); | ||
350 | 12 | INSERT INTO db2.t1 VALUES(4); | ||
351 | 13 | INSERT INTO db2.t1 VALUES(5); | ||
352 | 14 | UPDATE db2.t1 SET i= i+1; | ||
353 | 15 | DELETE FROM db2.t1 WHERE i=4; | ||
354 | 16 | call mtr.add_suppression("Slave SQL: Error executing row event:*"); | ||
355 | 17 | Dropping the database db1 creating the new database db3. | ||
356 | 18 | DROP DATABASE db1; | ||
357 | 19 | CREATE DATABASE db3; | ||
358 | 20 | DROP DATABASE db2; | ||
359 | 21 | RESET MASTER; | ||
360 | 22 | [The sql file will be applied on the current database] | ||
361 | 23 | [The content of table db3.t1 and db2.t1 will be different confirming no leak] | ||
362 | 24 | include/assert.inc [The content of the table t1 in database db3 and db2 is different] | ||
363 | 25 | include/assert.inc [Table t1 in db3 have different row count than t1 in db2] | ||
364 | 26 | CLEANUP | ||
365 | 27 | DROP DATABASE db1; | ||
366 | 28 | DROP DATABASE db2; | ||
367 | 29 | DROP DATABASE db3; | ||
368 | 0 | 30 | ||
369 | === added file 'mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result' | |||
370 | --- mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result 1970-01-01 00:00:00 +0000 | |||
371 | +++ mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result 2014-02-15 00:33:28 +0000 | |||
372 | @@ -0,0 +1,29 @@ | |||
373 | 1 | RESET MASTER; | ||
374 | 2 | CREATE DATABASE db1; | ||
375 | 3 | USE db1; | ||
376 | 4 | CREATE TABLE t1 (i INT); | ||
377 | 5 | INSERT INTO t1 VALUES(1); | ||
378 | 6 | INSERT INTO t1 VALUES(2); | ||
379 | 7 | UPDATE t1 SET i= i+1; | ||
380 | 8 | DELETE FROM t1 WHERE i=2; | ||
381 | 9 | [The use <db_name> is not suppressed in the general use of mysqlbinlog] | ||
382 | 10 | Matching lines are: | ||
383 | 11 | use `db1`/*!*/; | ||
384 | 12 | |||
385 | 13 | Occurrences of the use `db1` in the input file : 1 | ||
386 | 14 | [The use <db_name> is suppressed on using rewrite-db option of mysqlbinlog] | ||
387 | 15 | Matching lines are: | ||
388 | 16 | None | ||
389 | 17 | Occurrences of the use `db1` in the input file : 0 | ||
390 | 18 | CREATE DATABASE db2; | ||
391 | 19 | DROP DATABASE db1; | ||
392 | 20 | RESET MASTER; | ||
393 | 21 | SELECT * FROM db2.t1; | ||
394 | 22 | ERROR 42S02: Table 'db2.t1' doesn't exist | ||
395 | 23 | DROP DATABASE db1; | ||
396 | 24 | RESET MASTER; | ||
397 | 25 | [The event of table db1.t1 has been successfully applied to db2.t1] | ||
398 | 26 | include/assert.inc [Assert that table db2.t1 has no rows after applying the sql file.] | ||
399 | 27 | [CLEANUP] | ||
400 | 28 | DROP DATABASE db1; | ||
401 | 29 | DROP DATABASE db2; | ||
402 | 0 | 30 | ||
403 | === added file 'mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result' | |||
404 | --- mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result 1970-01-01 00:00:00 +0000 | |||
405 | +++ mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result 2014-02-15 00:33:28 +0000 | |||
406 | @@ -0,0 +1,152 @@ | |||
407 | 1 | # | ||
408 | 2 | # Apply log with '' | ||
409 | 3 | # | ||
410 | 4 | # use a | ||
411 | 5 | f | ||
412 | 6 | 0 | ||
413 | 7 | 0 | ||
414 | 8 | # use bbbbbbbbbbbbbbbbbbbb | ||
415 | 9 | f | ||
416 | 10 | 1 | ||
417 | 11 | 1 | ||
418 | 12 | # use cccccccccccccccc | ||
419 | 13 | f | ||
420 | 14 | 2 | ||
421 | 15 | 2 | ||
422 | 16 | # use d | ||
423 | 17 | f | ||
424 | 18 | # | ||
425 | 19 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="d"' | ||
426 | 20 | # | ||
427 | 21 | # use a | ||
428 | 22 | f | ||
429 | 23 | # use bbbbbbbbbbbbbbbbbbbb | ||
430 | 24 | f | ||
431 | 25 | # use cccccccccccccccc | ||
432 | 26 | f | ||
433 | 27 | # use d | ||
434 | 28 | f | ||
435 | 29 | 2 | ||
436 | 30 | 2 | ||
437 | 31 | # | ||
438 | 32 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="cccccccccccccccc"' | ||
439 | 33 | # | ||
440 | 34 | # use a | ||
441 | 35 | f | ||
442 | 36 | # use bbbbbbbbbbbbbbbbbbbb | ||
443 | 37 | f | ||
444 | 38 | # use cccccccccccccccc | ||
445 | 39 | f | ||
446 | 40 | # use d | ||
447 | 41 | f | ||
448 | 42 | # | ||
449 | 43 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="bbbbbbbbbbbbbbbbbbbb"' | ||
450 | 44 | # | ||
451 | 45 | # use a | ||
452 | 46 | f | ||
453 | 47 | # use bbbbbbbbbbbbbbbbbbbb | ||
454 | 48 | f | ||
455 | 49 | 0 | ||
456 | 50 | 0 | ||
457 | 51 | 1 | ||
458 | 52 | 1 | ||
459 | 53 | # use cccccccccccccccc | ||
460 | 54 | f | ||
461 | 55 | # use d | ||
462 | 56 | f | ||
463 | 57 | # | ||
464 | 58 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="a"' | ||
465 | 59 | # | ||
466 | 60 | # use a | ||
467 | 61 | f | ||
468 | 62 | # use bbbbbbbbbbbbbbbbbbbb | ||
469 | 63 | f | ||
470 | 64 | # use cccccccccccccccc | ||
471 | 65 | f | ||
472 | 66 | # use d | ||
473 | 67 | f | ||
474 | 68 | # | ||
475 | 69 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d"' | ||
476 | 70 | # | ||
477 | 71 | # use a | ||
478 | 72 | f | ||
479 | 73 | # use bbbbbbbbbbbbbbbbbbbb | ||
480 | 74 | f | ||
481 | 75 | 0 | ||
482 | 76 | 0 | ||
483 | 77 | 1 | ||
484 | 78 | 1 | ||
485 | 79 | # use cccccccccccccccc | ||
486 | 80 | f | ||
487 | 81 | # use d | ||
488 | 82 | f | ||
489 | 83 | 2 | ||
490 | 84 | 2 | ||
491 | 85 | # | ||
492 | 86 | # Apply log with '--rewrite-db=" a -> bbbbbbbbbbbbbbbbbbbb , cccccccccccccccc -> d "' | ||
493 | 87 | # | ||
494 | 88 | # use a | ||
495 | 89 | f | ||
496 | 90 | # use bbbbbbbbbbbbbbbbbbbb | ||
497 | 91 | f | ||
498 | 92 | 0 | ||
499 | 93 | 0 | ||
500 | 94 | 1 | ||
501 | 95 | 1 | ||
502 | 96 | # use cccccccccccccccc | ||
503 | 97 | f | ||
504 | 98 | # use d | ||
505 | 99 | f | ||
506 | 100 | 2 | ||
507 | 101 | 2 | ||
508 | 102 | # | ||
509 | 103 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb,cccccccccccccccc->d"' | ||
510 | 104 | # | ||
511 | 105 | # use a | ||
512 | 106 | f | ||
513 | 107 | # use bbbbbbbbbbbbbbbbbbbb | ||
514 | 108 | f | ||
515 | 109 | 0 | ||
516 | 110 | 0 | ||
517 | 111 | 1 | ||
518 | 112 | 1 | ||
519 | 113 | # use cccccccccccccccc | ||
520 | 114 | f | ||
521 | 115 | # use d | ||
522 | 116 | f | ||
523 | 117 | 2 | ||
524 | 118 | 2 | ||
525 | 119 | # | ||
526 | 120 | # Apply log with '--rewrite-db="a->d"' | ||
527 | 121 | # | ||
528 | 122 | # use a | ||
529 | 123 | f | ||
530 | 124 | # use bbbbbbbbbbbbbbbbbbbb | ||
531 | 125 | f | ||
532 | 126 | 1 | ||
533 | 127 | 1 | ||
534 | 128 | # use cccccccccccccccc | ||
535 | 129 | f | ||
536 | 130 | 2 | ||
537 | 131 | 2 | ||
538 | 132 | # use d | ||
539 | 133 | f | ||
540 | 134 | 0 | ||
541 | 135 | 0 | ||
542 | 136 | # | ||
543 | 137 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb"' | ||
544 | 138 | # | ||
545 | 139 | # use a | ||
546 | 140 | f | ||
547 | 141 | # use bbbbbbbbbbbbbbbbbbbb | ||
548 | 142 | f | ||
549 | 143 | 0 | ||
550 | 144 | 0 | ||
551 | 145 | 1 | ||
552 | 146 | 1 | ||
553 | 147 | # use cccccccccccccccc | ||
554 | 148 | f | ||
555 | 149 | 2 | ||
556 | 150 | 2 | ||
557 | 151 | # use d | ||
558 | 152 | f | ||
559 | 0 | 153 | ||
560 | === added file 'mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test' | |||
561 | --- mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test 1970-01-01 00:00:00 +0000 | |||
562 | +++ mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test 2014-02-15 00:33:28 +0000 | |||
563 | @@ -0,0 +1,95 @@ | |||
564 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
565 | 2 | # | ||
566 | 3 | # The test checks the new rewrite-db option for the mysqlbinlog. | ||
567 | 4 | # | ||
568 | 5 | # The test checks the following aspects of the new option: | ||
569 | 6 | |||
570 | 7 | # 1. The valid syntax for the use of the new option and the errors in | ||
571 | 8 | # case the usage is not correct. | ||
572 | 9 | # 2. Apply the new binlog file ( with database rewritten ) to a new database | ||
573 | 10 | # and check if it works. | ||
574 | 11 | # | ||
575 | 12 | --source include/have_binlog_format_row.inc | ||
576 | 13 | |||
577 | 14 | RESET MASTER; | ||
578 | 15 | CREATE DATABASE db1; | ||
579 | 16 | USE db1; | ||
580 | 17 | CREATE TABLE t1 (i INT); | ||
581 | 18 | |||
582 | 19 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
583 | 20 | INSERT INTO t1 VALUES(1); | ||
584 | 21 | INSERT INTO t1 VALUES(2); | ||
585 | 22 | UPDATE t1 SET i= i+1; | ||
586 | 23 | DELETE FROM t1 WHERE i=2; | ||
587 | 24 | |||
588 | 25 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
589 | 26 | --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
590 | 27 | |||
591 | 28 | # Using the new option to apply the row event on some other database (from db1 -> db2 in the current case) | ||
592 | 29 | |||
593 | 30 | --echo [Syntax error in the use of the new option: The from database name is missing] | ||
594 | 31 | --error 1 | ||
595 | 32 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
596 | 33 | |||
597 | 34 | --echo [Syntax error in the use of the new option: The '->' is missing] | ||
598 | 35 | --error 1 | ||
599 | 36 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1 db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
600 | 37 | |||
601 | 38 | --echo [Syntax error in the use of the new option: The to database name is missing] | ||
602 | 39 | --error 1 | ||
603 | 40 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
604 | 41 | |||
605 | 42 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 1] | ||
606 | 43 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2,db3->db4,db5->db6" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
607 | 44 | |||
608 | 45 | --echo [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4,db5->db6"] | ||
609 | 46 | --let log_file=mysqltest.log | ||
610 | 47 | --let log_file_full_path=$MYSQLTEST_VARDIR/log/current_test | ||
611 | 48 | --let grep_pattern=The comma-separated list of rewritings syntax is obsolete and discarded | ||
612 | 49 | --source include/log_grep.inc | ||
613 | 50 | |||
614 | 51 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 2] | ||
615 | 52 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2,db3->db4" --rewrite-db="db5->db6,db6->db7" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
616 | 53 | |||
617 | 54 | --echo [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4" --rewrite-db="db5->db6,db6->db7"] | ||
618 | 55 | --let log_file=mysqltest.log | ||
619 | 56 | --let log_file_full_path=$MYSQLTEST_VARDIR/log/current_test | ||
620 | 57 | --let grep_pattern=The comma-separated list of rewritings syntax is obsolete and discarded | ||
621 | 58 | --source include/log_grep.inc | ||
622 | 59 | |||
623 | 60 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned] | ||
624 | 61 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
625 | 62 | |||
626 | 63 | --echo #Dropping the database db1 and creating the table in the new database db2. | ||
627 | 64 | |||
628 | 65 | CREATE DATABASE db2; | ||
629 | 66 | DROP DATABASE db1; | ||
630 | 67 | |||
631 | 68 | # The SQL file will be applied but nothing is applied on Database db2 since the row event was | ||
632 | 69 | # generated for database db1 and table t1. | ||
633 | 70 | |||
634 | 71 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
635 | 72 | # replayed through mysqlbinlog will be skipped. | ||
636 | 73 | RESET MASTER; | ||
637 | 74 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
638 | 75 | --error ER_NO_SUCH_TABLE | ||
639 | 76 | SELECT * FROM db2.t1; | ||
640 | 77 | |||
641 | 78 | # The SQL file should be applied since the row event was extracted using the new mysqlbinlog option. | ||
642 | 79 | |||
643 | 80 | DROP DATABASE db1; | ||
644 | 81 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
645 | 82 | # replayed through mysqlbinlog will be skipped. | ||
646 | 83 | RESET MASTER; | ||
647 | 84 | --echo [The event of table db1.t1 has been successfully applied to db2.t1] | ||
648 | 85 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
649 | 86 | --let $assert_text= Assert that table db2.t1 has one row after applying the sql file. | ||
650 | 87 | --let $assert_cond= `SELECT COUNT(*)=1 from db2.t1` | ||
651 | 88 | --source include/assert.inc | ||
652 | 89 | |||
653 | 90 | --echo CLEANUP | ||
654 | 91 | |||
655 | 92 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
656 | 93 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
657 | 94 | DROP DATABASE db1; | ||
658 | 95 | DROP DATABASE db2; | ||
659 | 0 | 96 | ||
660 | === added file 'mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test' | |||
661 | --- mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test 1970-01-01 00:00:00 +0000 | |||
662 | +++ mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test 2014-02-15 00:33:28 +0000 | |||
663 | @@ -0,0 +1,79 @@ | |||
664 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
665 | 2 | # | ||
666 | 3 | # The test checks that there is no leak of the global variables used | ||
667 | 4 | # to decide whether rewrite-db option is ON or OFF. | ||
668 | 5 | # | ||
669 | 6 | # The test checks this by creating two tables in two different databases. | ||
670 | 7 | # insert rows in both of them. | ||
671 | 8 | # | ||
672 | 9 | # Read the binlog file using the new option --rewrite-db="db1->db3" and | ||
673 | 10 | # writing in the .sql file. | ||
674 | 11 | # | ||
675 | 12 | # On applying the .sql file on database db3, we get an error since not | ||
676 | 13 | # all events are converted for database db3. Only DB1 is converted to db3. | ||
677 | 14 | # The db2 event cause the error. | ||
678 | 15 | # | ||
679 | 16 | |||
680 | 17 | --source include/have_binlog_format_row.inc | ||
681 | 18 | RESET MASTER; | ||
682 | 19 | CREATE DATABASE db1; | ||
683 | 20 | USE db1; | ||
684 | 21 | CREATE TABLE t1 (i INT); | ||
685 | 22 | |||
686 | 23 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
687 | 24 | INSERT INTO db1.t1 VALUES(1); | ||
688 | 25 | INSERT INTO db1.t1 VALUES(2); | ||
689 | 26 | UPDATE t1 SET i= i+1; | ||
690 | 27 | DELETE FROM t1 WHERE i=2; | ||
691 | 28 | |||
692 | 29 | CREATE DATABASE db2; | ||
693 | 30 | CREATE TABLE db2.t1 (i INT); | ||
694 | 31 | |||
695 | 32 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
696 | 33 | INSERT INTO db2.t1 VALUES(3); | ||
697 | 34 | INSERT INTO db2.t1 VALUES(4); | ||
698 | 35 | INSERT INTO db2.t1 VALUES(5); | ||
699 | 36 | UPDATE db2.t1 SET i= i+1; | ||
700 | 37 | DELETE FROM db2.t1 WHERE i=4; | ||
701 | 38 | |||
702 | 39 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
703 | 40 | |||
704 | 41 | # Using the new option to apply the row event on some other database (from db1 -> db3 in the current case) | ||
705 | 42 | |||
706 | 43 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db3" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
707 | 44 | call mtr.add_suppression("Slave SQL: Error executing row event:*"); | ||
708 | 45 | |||
709 | 46 | --echo Dropping the database db1 creating the new database db3. | ||
710 | 47 | DROP DATABASE db1; | ||
711 | 48 | CREATE DATABASE db3; | ||
712 | 49 | |||
713 | 50 | # The SQL file will be applied but only db1 events will be replayed on db3. | ||
714 | 51 | # Database db2 will not be applied on db3 confirming there is no leak. | ||
715 | 52 | DROP DATABASE db2; | ||
716 | 53 | |||
717 | 54 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
718 | 55 | # replayed through mysqlbinlog will be skipped. | ||
719 | 56 | RESET MASTER; | ||
720 | 57 | --echo [The sql file will be applied on the current database] | ||
721 | 58 | --exec $MYSQL --database=db3 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
722 | 59 | |||
723 | 60 | --echo [The content of table db3.t1 and db2.t1 will be different confirming no leak] | ||
724 | 61 | |||
725 | 62 | --let $db3_max= `SELECT MAX(i) FROM db3.t1` | ||
726 | 63 | --let $db2_max= `SELECT MAX(i) FROM db2.t1` | ||
727 | 64 | --let $assert_text= The content of the table t1 in database db3 and db2 is different | ||
728 | 65 | --let $assert_cond= $db3_max <> $db2_max | ||
729 | 66 | --source include/assert.inc | ||
730 | 67 | |||
731 | 68 | --let $db3_count= `SELECT COUNT(*) FROM db3.t1` | ||
732 | 69 | --let $db2_count= `SELECT COUNT(*) FROM db2.t1` | ||
733 | 70 | --let $assert_text= Table t1 in db3 have different row count than t1 in db2 | ||
734 | 71 | --let $assert_cond= $db3_count=1 AND $db2_count<>1 | ||
735 | 72 | --source include/assert.inc | ||
736 | 73 | |||
737 | 74 | --echo CLEANUP | ||
738 | 75 | |||
739 | 76 | #--remove_file $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
740 | 77 | DROP DATABASE db1; | ||
741 | 78 | DROP DATABASE db2; | ||
742 | 79 | DROP DATABASE db3; | ||
743 | 0 | 80 | ||
744 | === added file 'mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test' | |||
745 | --- mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test 1970-01-01 00:00:00 +0000 | |||
746 | +++ mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test 2014-02-15 00:33:28 +0000 | |||
747 | @@ -0,0 +1,61 @@ | |||
748 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
749 | 2 | # | ||
750 | 3 | # The test aims to check that the use of rewrite-db option of | ||
751 | 4 | # mysqlbinlog suppresses the USE DATABASE command logged in | ||
752 | 5 | # binlog file. | ||
753 | 6 | # | ||
754 | 7 | |||
755 | 8 | --source include/have_binlog_format_row.inc | ||
756 | 9 | RESET MASTER; | ||
757 | 10 | CREATE DATABASE db1; | ||
758 | 11 | USE db1; | ||
759 | 12 | CREATE TABLE t1 (i INT); | ||
760 | 13 | |||
761 | 14 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
762 | 15 | INSERT INTO t1 VALUES(1); | ||
763 | 16 | INSERT INTO t1 VALUES(2); | ||
764 | 17 | UPDATE t1 SET i= i+1; | ||
765 | 18 | DELETE FROM t1 WHERE i=2; | ||
766 | 19 | |||
767 | 20 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
768 | 21 | |||
769 | 22 | # Checking for the suppression of the USE DATABASE command on using the new option. | ||
770 | 23 | # Reading binlog file without the rewrite-db option. | ||
771 | 24 | --echo [The use <db_name> is not suppressed in the general use of mysqlbinlog] | ||
772 | 25 | --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
773 | 26 | --let GREP_FILE=$MYSQLTEST_VARDIR/tmp/row_event.sql | ||
774 | 27 | --let GREP_PATTERN=use `db1` | ||
775 | 28 | --source extra/rpl_tests/grep_pattern.inc | ||
776 | 29 | |||
777 | 30 | # Reading binlog file with the rewrite-db option. | ||
778 | 31 | --echo [The use <db_name> is suppressed on using rewrite-db option of mysqlbinlog] | ||
779 | 32 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
780 | 33 | --let GREP_FILE=$MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
781 | 34 | --let GREP_PATTERN=use `db1` | ||
782 | 35 | --source extra/rpl_tests/grep_pattern.inc | ||
783 | 36 | |||
784 | 37 | CREATE DATABASE db2; | ||
785 | 38 | DROP DATABASE db1; | ||
786 | 39 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
787 | 40 | # replayed through mysqlbinlog will be skipped. | ||
788 | 41 | RESET MASTER; | ||
789 | 42 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
790 | 43 | --error ER_NO_SUCH_TABLE | ||
791 | 44 | SELECT * FROM db2.t1; | ||
792 | 45 | |||
793 | 46 | DROP DATABASE db1; | ||
794 | 47 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
795 | 48 | # replayed through mysqlbinlog will be skipped. | ||
796 | 49 | RESET MASTER; | ||
797 | 50 | --echo [The event of table db1.t1 has been successfully applied to db2.t1] | ||
798 | 51 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
799 | 52 | --let $assert_text= Assert that table db2.t1 has no rows after applying the sql file. | ||
800 | 53 | --let $assert_cond= `SELECT COUNT(*)=1 from db2.t1` | ||
801 | 54 | --source include/assert.inc | ||
802 | 55 | |||
803 | 56 | --echo [CLEANUP] | ||
804 | 57 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
805 | 58 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
806 | 59 | |||
807 | 60 | DROP DATABASE db1; | ||
808 | 61 | DROP DATABASE db2; | ||
809 | 0 | 62 | ||
810 | === added file 'mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt' | |||
811 | --- mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt 1970-01-01 00:00:00 +0000 | |||
812 | +++ mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt 2014-02-15 00:33:28 +0000 | |||
813 | @@ -0,0 +1,1 @@ | |||
814 | 1 | --local-infile=1 | ||
815 | 0 | 2 | ||
816 | === added file 'mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test' | |||
817 | --- mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test 1970-01-01 00:00:00 +0000 | |||
818 | +++ mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test 2014-02-15 00:33:28 +0000 | |||
819 | @@ -0,0 +1,80 @@ | |||
820 | 1 | --source include/have_log_bin.inc | ||
821 | 2 | # | ||
822 | 3 | # WL #36: http://askmonty.org/worklog/Server-Sprint/?tid=36 | ||
823 | 4 | # This is basic test for --rewrite-db option. | ||
824 | 5 | # mysqlbinlog --rewrite-db="from->to" should rewrite database name | ||
825 | 6 | # | ||
826 | 7 | |||
827 | 8 | --disable_query_log | ||
828 | 9 | |||
829 | 10 | # Because RBR event DB rewrite requires shifting of | ||
830 | 11 | # Table_map_log_event contents around if the DB name length | ||
831 | 12 | # changes, this case is tested for both shorter and longer | ||
832 | 13 | # names. | ||
833 | 14 | |||
834 | 15 | --let DB1=a | ||
835 | 16 | --let DB2=bbbbbbbbbbbbbbbbbbbb | ||
836 | 17 | --let DB3=cccccccccccccccc | ||
837 | 18 | --let DB4=d | ||
838 | 19 | |||
839 | 20 | eval CREATE DATABASE $DB1; eval USE $DB1; CREATE TABLE t1(f INT); | ||
840 | 21 | eval CREATE DATABASE $DB2; eval USE $DB2; CREATE TABLE t1(f INT); | ||
841 | 22 | eval CREATE DATABASE $DB3; eval USE $DB3; CREATE TABLE t1(f INT); | ||
842 | 23 | eval CREATE DATABASE $DB4; eval USE $DB4; CREATE TABLE t1(f INT); | ||
843 | 24 | |||
844 | 25 | RESET MASTER; | ||
845 | 26 | --let MYSQLD_DATA_DIR=`select @@datadir` | ||
846 | 27 | --let LOAD_DATA_FILE=$MYSQLD_DATA_DIR/table.values | ||
847 | 28 | --let BIN_LOG_FILE_NAME=query_get_value(show master status, File, 1) | ||
848 | 29 | --let BIN_LOG_START_POSITION=query_get_value(show master status, Position, 1) | ||
849 | 30 | eval USE $DB1; INSERT INTO t1 VALUES(0); INSERT INTO t1 VALUES(0); | ||
850 | 31 | eval USE $DB2; INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1); | ||
851 | 32 | write_file $LOAD_DATA_FILE; | ||
852 | 33 | 2 | ||
853 | 34 | 2 | ||
854 | 35 | EOF | ||
855 | 36 | eval USE $DB3; | ||
856 | 37 | --eval LOAD DATA INFILE "$LOAD_DATA_FILE" INTO TABLE t1 | ||
857 | 38 | --let BIN_LOG_STOP_POSITION=query_get_value(show master status, Position, 1) | ||
858 | 39 | FLUSH LOGS; | ||
859 | 40 | |||
860 | 41 | --let BIN_LOG_FULL_PATH=`SELECT CONCAT("$MYSQLD_DATA_DIR", "$BIN_LOG_FILE_NAME")` | ||
861 | 42 | |||
862 | 43 | --let i=10 | ||
863 | 44 | |||
864 | 45 | while ($i) | ||
865 | 46 | { | ||
866 | 47 | # Test for different combinations of syntax and db name filtering and rewriting | ||
867 | 48 | --let REWRITE=`SELECT CASE $i WHEN 10 THEN '' WHEN 9 THEN '--rewrite-db="$DB1->$DB2" --rewrite-db="$DB3->$DB4" --database="$DB4"' WHEN 8 THEN '--rewrite-db="$DB1->$DB2" --rewrite-db="$DB3->$DB4" --database="$DB3"' WHEN 7 THEN '--rewrite-db="$DB1->$DB2" --rewrite-db="$DB3->$DB4" --database="$DB2"' WHEN 6 THEN '--rewrite-db="$DB1->$DB2" --rewrite-db="$DB3->$DB4" --database="$DB1"' WHEN 5 THEN '--rewrite-db="$DB1->$DB2" --rewrite-db="$DB3->$DB4"' WHEN 4 THEN '--rewrite-db=" $DB1 -> $DB2 , $DB3 -> $DB4 "' WHEN 3 THEN '--rewrite-db="$DB1->$DB2,$DB3->$DB4"' WHEN 2 THEN '--rewrite-db="$DB1->$DB4"' WHEN 1 THEN '--rewrite-db="$DB1->$DB2"' END` | ||
868 | 49 | |||
869 | 50 | eval USE $DB1; DELETE FROM t1; | ||
870 | 51 | eval USE $DB2; DELETE FROM t1; | ||
871 | 52 | eval USE $DB3; DELETE FROM t1; | ||
872 | 53 | eval USE $DB4; DELETE FROM t1; | ||
873 | 54 | |||
874 | 55 | --echo # | ||
875 | 56 | --echo # Apply log with '$REWRITE' | ||
876 | 57 | --echo # | ||
877 | 58 | |||
878 | 59 | --exec $MYSQL_BINLOG $REWRITE --start-position=$BIN_LOG_START_POSITION --stop-position=$BIN_LOG_STOP_POSITION $BIN_LOG_FULL_PATH | $MYSQL --local-infile=1 | ||
879 | 60 | |||
880 | 61 | --echo # use $DB1 | ||
881 | 62 | eval USE $DB1; SELECT * FROM t1 ORDER BY f; | ||
882 | 63 | --echo # use $DB2 | ||
883 | 64 | eval USE $DB2; SELECT * FROM t1 ORDER BY f; | ||
884 | 65 | --echo # use $DB3 | ||
885 | 66 | eval USE $DB3; SELECT * FROM t1 ORDER BY f; | ||
886 | 67 | --echo # use $DB4 | ||
887 | 68 | eval USE $DB4; SELECT * FROM t1 ORDER BY f; | ||
888 | 69 | |||
889 | 70 | dec $i; | ||
890 | 71 | } | ||
891 | 72 | |||
892 | 73 | eval USE $DB1; DROP TABLE t1; eval DROP DATABASE $DB1; | ||
893 | 74 | eval USE $DB2; DROP TABLE t1; eval DROP DATABASE $DB2; | ||
894 | 75 | eval USE $DB3; DROP TABLE t1; eval DROP DATABASE $DB3; | ||
895 | 76 | eval USE $DB4; DROP TABLE t1; eval DROP DATABASE $DB4; | ||
896 | 77 | |||
897 | 78 | --remove_file $LOAD_DATA_FILE | ||
898 | 79 | |||
899 | 80 | --enable_query_log | ||
900 | 0 | 81 | ||
901 | === modified file 'sql/log_event.cc' | |||
902 | --- sql/log_event.cc 2014-02-03 04:39:37 +0000 | |||
903 | +++ sql/log_event.cc 2014-02-15 00:33:28 +0000 | |||
904 | @@ -8714,6 +8714,108 @@ | |||
905 | 8714 | my_free(m_memory); | 8714 | my_free(m_memory); |
906 | 8715 | } | 8715 | } |
907 | 8716 | 8716 | ||
908 | 8717 | #ifdef MYSQL_CLIENT | ||
909 | 8718 | |||
910 | 8719 | /* | ||
911 | 8720 | Rewrite database name for the event to name specified by new_db | ||
912 | 8721 | SYNOPSIS | ||
913 | 8722 | new_db Database name to change to | ||
914 | 8723 | new_len Length | ||
915 | 8724 | desc Event describing binlog that we're writing to. | ||
916 | 8725 | |||
917 | 8726 | DESCRIPTION | ||
918 | 8727 | Reset db name. This function assumes that temp_buf member contains event | ||
919 | 8728 | representation taken from a binary log. It resets m_dbnam and m_dblen and | ||
920 | 8729 | rewrites temp_buf with new db name. | ||
921 | 8730 | |||
922 | 8731 | RETURN | ||
923 | 8732 | 0 - Success | ||
924 | 8733 | other - Error | ||
925 | 8734 | */ | ||
926 | 8735 | |||
927 | 8736 | int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len, | ||
928 | 8737 | const Format_description_log_event* desc) | ||
929 | 8738 | { | ||
930 | 8739 | DBUG_ENTER("Table_map_log_event::rewrite_db"); | ||
931 | 8740 | DBUG_ASSERT(temp_buf); | ||
932 | 8741 | |||
933 | 8742 | uint header_len= min(desc->common_header_len, | ||
934 | 8743 | LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN; | ||
935 | 8744 | int len_diff; | ||
936 | 8745 | |||
937 | 8746 | if (!(len_diff= new_len - m_dblen)) | ||
938 | 8747 | { | ||
939 | 8748 | memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1); | ||
940 | 8749 | memcpy((void*) m_dbnam, new_db, m_dblen + 1); | ||
941 | 8750 | DBUG_RETURN(0); | ||
942 | 8751 | } | ||
943 | 8752 | |||
944 | 8753 | // Create new temp_buf | ||
945 | 8754 | ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET); | ||
946 | 8755 | ulong event_new_len= event_cur_len + len_diff; | ||
947 | 8756 | char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME)); | ||
948 | 8757 | |||
949 | 8758 | if (!new_temp_buf) | ||
950 | 8759 | { | ||
951 | 8760 | sql_print_error("Table_map_log_event::rewrite_db: " | ||
952 | 8761 | "failed to allocate new temp_buf (%d bytes required)", | ||
953 | 8762 | event_new_len); | ||
954 | 8763 | DBUG_RETURN(-1); | ||
955 | 8764 | } | ||
956 | 8765 | |||
957 | 8766 | // Rewrite temp_buf | ||
958 | 8767 | char* ptr= new_temp_buf; | ||
959 | 8768 | ulong cnt= 0; | ||
960 | 8769 | |||
961 | 8770 | // Copy header and change event length | ||
962 | 8771 | memcpy(ptr, temp_buf, header_len); | ||
963 | 8772 | int4store(ptr + EVENT_LEN_OFFSET, event_new_len); | ||
964 | 8773 | ptr += header_len; | ||
965 | 8774 | cnt += header_len; | ||
966 | 8775 | |||
967 | 8776 | // Write new db name length and new name | ||
968 | 8777 | *ptr++ = new_len; | ||
969 | 8778 | memcpy(ptr, new_db, new_len + 1); | ||
970 | 8779 | ptr += new_len + 1; | ||
971 | 8780 | cnt += m_dblen + 2; | ||
972 | 8781 | |||
973 | 8782 | // Copy rest part | ||
974 | 8783 | memcpy(ptr, temp_buf + cnt, event_cur_len - cnt); | ||
975 | 8784 | |||
976 | 8785 | // Reregister temp buf | ||
977 | 8786 | free_temp_buf(); | ||
978 | 8787 | register_temp_buf(new_temp_buf); | ||
979 | 8788 | |||
980 | 8789 | // Reset m_dbnam and m_dblen members | ||
981 | 8790 | m_dblen= new_len; | ||
982 | 8791 | |||
983 | 8792 | // m_dbnam resides in m_memory together with m_tblnam and m_coltype | ||
984 | 8793 | uchar* memory= m_memory; | ||
985 | 8794 | char const* tblnam= m_tblnam; | ||
986 | 8795 | uchar* coltype= m_coltype; | ||
987 | 8796 | |||
988 | 8797 | m_memory= (uchar*) my_multi_malloc(MYF(MY_WME), | ||
989 | 8798 | &m_dbnam, (uint) m_dblen + 1, | ||
990 | 8799 | &m_tblnam, (uint) m_tbllen + 1, | ||
991 | 8800 | &m_coltype, (uint) m_colcnt, | ||
992 | 8801 | NullS); | ||
993 | 8802 | |||
994 | 8803 | if (!m_memory) | ||
995 | 8804 | { | ||
996 | 8805 | sql_print_error("Table_map_log_event::rewrite_db: " | ||
997 | 8806 | "failed to allocate new m_memory (%d + %d + %d bytes required)", | ||
998 | 8807 | m_dblen + 1, m_tbllen + 1, m_colcnt); | ||
999 | 8808 | DBUG_RETURN(-1); | ||
1000 | 8809 | } | ||
1001 | 8810 | |||
1002 | 8811 | memcpy((void*)m_dbnam, new_db, m_dblen + 1); | ||
1003 | 8812 | memcpy((void*)m_tblnam, tblnam, m_tbllen + 1); | ||
1004 | 8813 | memcpy(m_coltype, coltype, m_colcnt); | ||
1005 | 8814 | |||
1006 | 8815 | my_free(memory); | ||
1007 | 8816 | DBUG_RETURN(0); | ||
1008 | 8817 | } | ||
1009 | 8818 | #endif /* MYSQL_CLIENT */ | ||
1010 | 8717 | /* | 8819 | /* |
1011 | 8718 | Return value is an error code, one of: | 8820 | Return value is an error code, one of: |
1012 | 8719 | 8821 | ||
1013 | 8720 | 8822 | ||
1014 | === modified file 'sql/log_event.h' | |||
1015 | --- sql/log_event.h 2014-02-03 04:39:37 +0000 | |||
1016 | +++ sql/log_event.h 2014-02-15 00:33:28 +0000 | |||
1017 | @@ -3504,7 +3504,10 @@ | |||
1018 | 3504 | ulong get_table_id() const { return m_table_id; } | 3504 | ulong get_table_id() const { return m_table_id; } |
1019 | 3505 | const char *get_table_name() const { return m_tblnam; } | 3505 | const char *get_table_name() const { return m_tblnam; } |
1020 | 3506 | const char *get_db_name() const { return m_dbnam; } | 3506 | const char *get_db_name() const { return m_dbnam; } |
1022 | 3507 | 3507 | #ifdef MYSQL_CLIENT | |
1023 | 3508 | int rewrite_db(const char* new_name, size_t new_name_len, | ||
1024 | 3509 | const Format_description_log_event*); | ||
1025 | 3510 | #endif | ||
1026 | 3508 | virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } | 3511 | virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } |
1027 | 3509 | virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } | 3512 | virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } |
1028 | 3510 | 3513 |
same comment as 5.6:
It states that you can do "a->b,c->d" but I don't see the handling for the comma in the mysqlbinlog.cc command line parsing. Am I missing something? We should also test this.