Merge lp:~vlad-lesin/percona-server/5.6-mysqlbinlog-replacedb into lp:percona-server/5.6
- 5.6-mysqlbinlog-replacedb
- Merge into 5.6
Status: | Merged |
---|---|
Approved by: | Laurynas Biveinis |
Approved revision: | no longer in the source branch. |
Merged at revision: | 544 |
Proposed branch: | lp:~vlad-lesin/percona-server/5.6-mysqlbinlog-replacedb |
Merge into: | lp:percona-server/5.6 |
Diff against target: |
1011 lines (+850/-2) 15 files modified
client/CMakeLists.txt (+2/-1) client/client_priv.h (+1/-0) client/mysqlbinlog.cc (+160/-0) 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) |
To merge this branch: | bzr merge lp:~vlad-lesin/percona-server/5.6-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+196583@code.launchpad.net |
Commit message
Description of the change
Merged from 5.5.
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://
The following changes are between 5.5 and 5.6:
1) Define "CHARSET_INFO* table_alias_
2) process_event() differs because the original code differs too.
George Ormond Lorch III (gl-az) : | # |
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
See 5.5 comments.
Vlad Lesin (vlad-lesin) wrote : | # |
> See 5.5 comments.
Fixed, http://
Also there is a memory leak in mysql-5.7.3 when --rewrite-db option is used. Here is the bug report http://
Vlad Lesin (vlad-lesin) wrote : | # |
Vlad Lesin (vlad-lesin) wrote : | # |
See 5.5 comments.
http://
Laurynas Biveinis (laurynas-biveinis) : | # |
Laurynas Biveinis (laurynas-biveinis) : | # |
Preview Diff
1 | === modified file 'client/CMakeLists.txt' | |||
2 | --- client/CMakeLists.txt 2013-10-08 06:03:07 +0000 | |||
3 | +++ client/CMakeLists.txt 2014-02-15 00:30:14 +0000 | |||
4 | @@ -61,7 +61,8 @@ | |||
5 | 61 | MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c) | 61 | MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c) |
6 | 62 | TARGET_LINK_LIBRARIES(mysql_plugin perconaserverclient) | 62 | TARGET_LINK_LIBRARIES(mysql_plugin perconaserverclient) |
7 | 63 | 63 | ||
9 | 64 | MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc sql_string.cc) | 64 | MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc sql_string.cc |
10 | 65 | ../sql/rpl_filter.cc ../sql/sql_list.cc) | ||
11 | 65 | TARGET_LINK_LIBRARIES(mysqlbinlog perconaserverclient) | 66 | TARGET_LINK_LIBRARIES(mysqlbinlog perconaserverclient) |
12 | 66 | 67 | ||
13 | 67 | MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc) | 68 | MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc) |
14 | 68 | 69 | ||
15 | === modified file 'client/client_priv.h' | |||
16 | --- client/client_priv.h 2013-06-25 13:13:06 +0000 | |||
17 | +++ client/client_priv.h 2014-02-15 00:30:14 +0000 | |||
18 | @@ -104,6 +104,7 @@ | |||
19 | 104 | OPT_SERVER_PUBLIC_KEY, | 104 | OPT_SERVER_PUBLIC_KEY, |
20 | 105 | OPT_ENABLE_CLEARTEXT_PLUGIN, | 105 | OPT_ENABLE_CLEARTEXT_PLUGIN, |
21 | 106 | OPT_INNODB_OPTIMIZE_KEYS, | 106 | OPT_INNODB_OPTIMIZE_KEYS, |
22 | 107 | OPT_REWRITE_DB, | ||
23 | 107 | OPT_MAX_CLIENT_OPTION | 108 | OPT_MAX_CLIENT_OPTION |
24 | 108 | }; | 109 | }; |
25 | 109 | 110 | ||
26 | 110 | 111 | ||
27 | === modified file 'client/mysqlbinlog.cc' | |||
28 | --- client/mysqlbinlog.cc 2013-10-31 18:42:25 +0000 | |||
29 | +++ client/mysqlbinlog.cc 2014-02-15 00:30:14 +0000 | |||
30 | @@ -60,6 +60,18 @@ | |||
31 | 60 | using std::min; | 60 | using std::min; |
32 | 61 | using std::max; | 61 | using std::max; |
33 | 62 | 62 | ||
34 | 63 | /* Needed for Rpl_filter */ | ||
35 | 64 | CHARSET_INFO *table_alias_charset= &my_charset_bin; | ||
36 | 65 | |||
37 | 66 | #include "rpl_filter.h" | ||
38 | 67 | |||
39 | 68 | /* | ||
40 | 69 | True if obsolette syntax warning has been already shown | ||
41 | 70 | during parsing --rewrite-db command line option | ||
42 | 71 | */ | ||
43 | 72 | bool rewrite_db_obs_syn_warn= false; | ||
44 | 73 | Rpl_filter *binlog_filter= NULL; | ||
45 | 74 | |||
46 | 63 | #define BIN_LOG_HEADER_SIZE 4U | 75 | #define BIN_LOG_HEADER_SIZE 4U |
47 | 64 | #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) | 76 | #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) |
48 | 65 | #define INTVAR_DYNAMIC_INIT 16 | 77 | #define INTVAR_DYNAMIC_INIT 16 |
49 | @@ -712,6 +724,35 @@ | |||
50 | 712 | strcmp(log_dbname, database); | 724 | strcmp(log_dbname, database); |
51 | 713 | } | 725 | } |
52 | 714 | 726 | ||
53 | 727 | /** | ||
54 | 728 | Rewrites db name in T instance if binlog_filter contains | ||
55 | 729 | name for replacement(see --rewrite-db option). | ||
56 | 730 | |||
57 | 731 | T::db must be weak pointer and can point to the memory owned by | ||
58 | 732 | "binlog_filter" after this function execution, that is why "ev" must be | ||
59 | 733 | destroyed before "binlog_filter". | ||
60 | 734 | |||
61 | 735 | @param ev Event to process | ||
62 | 736 | */ | ||
63 | 737 | template <typename T> | ||
64 | 738 | static void rewrite_db(T &ev) | ||
65 | 739 | { | ||
66 | 740 | size_t len_to= 0; | ||
67 | 741 | const char* db_to; | ||
68 | 742 | |||
69 | 743 | DBUG_ASSERT(binlog_filter); | ||
70 | 744 | |||
71 | 745 | if (!ev.db) | ||
72 | 746 | return; | ||
73 | 747 | |||
74 | 748 | db_to= binlog_filter->get_rewrite_db(ev.db, &len_to); | ||
75 | 749 | |||
76 | 750 | if (!len_to) | ||
77 | 751 | return; | ||
78 | 752 | |||
79 | 753 | ev.db= db_to; | ||
80 | 754 | ev.db_len= len_to; | ||
81 | 755 | } | ||
82 | 715 | 756 | ||
83 | 716 | /** | 757 | /** |
84 | 717 | Checks whether the given event should be filtered out, | 758 | Checks whether the given event should be filtered out, |
85 | @@ -898,6 +939,13 @@ | |||
86 | 898 | switch (ev_type) { | 939 | switch (ev_type) { |
87 | 899 | case QUERY_EVENT: | 940 | case QUERY_EVENT: |
88 | 900 | { | 941 | { |
89 | 942 | /* | ||
90 | 943 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
91 | 944 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
92 | 945 | */ | ||
93 | 946 | if (binlog_filter) | ||
94 | 947 | rewrite_db(*static_cast<Query_log_event *>(ev)); | ||
95 | 948 | |||
96 | 901 | bool parent_query_skips= | 949 | bool parent_query_skips= |
97 | 902 | !((Query_log_event*) ev)->is_trans_keyword() && | 950 | !((Query_log_event*) ev)->is_trans_keyword() && |
98 | 903 | shall_skip_database(((Query_log_event*) ev)->db); | 951 | shall_skip_database(((Query_log_event*) ev)->db); |
99 | @@ -989,6 +1037,12 @@ | |||
100 | 989 | { | 1037 | { |
101 | 990 | Create_file_log_event* ce= (Create_file_log_event*)ev; | 1038 | Create_file_log_event* ce= (Create_file_log_event*)ev; |
102 | 991 | /* | 1039 | /* |
103 | 1040 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
104 | 1041 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
105 | 1042 | */ | ||
106 | 1043 | if (binlog_filter) | ||
107 | 1044 | rewrite_db(*ce); | ||
108 | 1045 | /* | ||
109 | 992 | We test if this event has to be ignored. If yes, we don't save | 1046 | We test if this event has to be ignored. If yes, we don't save |
110 | 993 | this event; this will have the good side-effect of ignoring all | 1047 | this event; this will have the good side-effect of ignoring all |
111 | 994 | related Append_block and Exec_load. | 1048 | related Append_block and Exec_load. |
112 | @@ -1115,6 +1169,12 @@ | |||
113 | 1115 | case EXECUTE_LOAD_QUERY_EVENT: | 1169 | case EXECUTE_LOAD_QUERY_EVENT: |
114 | 1116 | { | 1170 | { |
115 | 1117 | Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; | 1171 | Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev; |
116 | 1172 | /* | ||
117 | 1173 | ev is deleted at the end of this function(before binlog_filter deletion) | ||
118 | 1174 | so it is safe to set ev->db to some memory owned by binlog_filter here. | ||
119 | 1175 | */ | ||
120 | 1176 | if (binlog_filter) | ||
121 | 1177 | rewrite_db(*exlq); | ||
122 | 1118 | char *fname= load_processor.grab_fname(exlq->file_id); | 1178 | char *fname= load_processor.grab_fname(exlq->file_id); |
123 | 1119 | 1179 | ||
124 | 1120 | if (shall_skip_database(exlq->db)) | 1180 | if (shall_skip_database(exlq->db)) |
125 | @@ -1144,6 +1204,19 @@ | |||
126 | 1144 | case TABLE_MAP_EVENT: | 1204 | case TABLE_MAP_EVENT: |
127 | 1145 | { | 1205 | { |
128 | 1146 | Table_map_log_event *map= ((Table_map_log_event *)ev); | 1206 | Table_map_log_event *map= ((Table_map_log_event *)ev); |
129 | 1207 | // Rewrite db name here (see --rewrite-db option) | ||
130 | 1208 | if (binlog_filter) | ||
131 | 1209 | { | ||
132 | 1210 | size_t len_to= 0; | ||
133 | 1211 | const char* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), | ||
134 | 1212 | &len_to); | ||
135 | 1213 | if (len_to && map->rewrite_db(db_to, len_to, glob_description_event)) | ||
136 | 1214 | { | ||
137 | 1215 | error("Could not rewrite database name"); | ||
138 | 1216 | goto err; | ||
139 | 1217 | } | ||
140 | 1218 | } | ||
141 | 1219 | |||
142 | 1147 | if (shall_skip_database(map->get_db_name())) | 1220 | if (shall_skip_database(map->get_db_name())) |
143 | 1148 | { | 1221 | { |
144 | 1149 | print_event_info->skipped_event_in_transaction= true; | 1222 | print_event_info->skipped_event_in_transaction= true; |
145 | @@ -1589,6 +1662,10 @@ | |||
146 | 1589 | "Identifiers were provided.", | 1662 | "Identifiers were provided.", |
147 | 1590 | &opt_exclude_gtids_str, &opt_exclude_gtids_str, 0, | 1663 | &opt_exclude_gtids_str, &opt_exclude_gtids_str, 0, |
148 | 1591 | GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | 1664 | GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
149 | 1665 | {"rewrite-db", OPT_REWRITE_DB, | ||
150 | 1666 | "Updates to a database with a different name than the original. " | ||
151 | 1667 | "Example: rewrite-db='from->to'.", | ||
152 | 1668 | 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | ||
153 | 1592 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} | 1669 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
154 | 1593 | }; | 1670 | }; |
155 | 1594 | 1671 | ||
156 | @@ -1674,6 +1751,7 @@ | |||
157 | 1674 | delete_dynamic(&buff_ev); | 1751 | delete_dynamic(&buff_ev); |
158 | 1675 | 1752 | ||
159 | 1676 | delete glob_description_event; | 1753 | delete glob_description_event; |
160 | 1754 | delete binlog_filter; | ||
161 | 1677 | if (mysql) | 1755 | if (mysql) |
162 | 1678 | mysql_close(mysql); | 1756 | mysql_close(mysql); |
163 | 1679 | } | 1757 | } |
164 | @@ -1773,6 +1851,88 @@ | |||
165 | 1773 | opt_base64_output_mode= (enum_base64_output_mode) | 1851 | opt_base64_output_mode= (enum_base64_output_mode) |
166 | 1774 | (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); | 1852 | (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); |
167 | 1775 | break; | 1853 | break; |
168 | 1854 | case OPT_REWRITE_DB: // db_from->db_to | ||
169 | 1855 | { | ||
170 | 1856 | /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ | ||
171 | 1857 | char* ptr= argument; | ||
172 | 1858 | do { | ||
173 | 1859 | char* key= ptr; // db-from | ||
174 | 1860 | char* val; // db-to | ||
175 | 1861 | |||
176 | 1862 | // Where key begins | ||
177 | 1863 | while (*key && my_isspace(&my_charset_latin1, *key)) | ||
178 | 1864 | key++; | ||
179 | 1865 | |||
180 | 1866 | // Where val begins | ||
181 | 1867 | if (!(ptr= strstr(key, "->"))) | ||
182 | 1868 | { | ||
183 | 1869 | sql_print_error("Bad syntax in rewrite-db: missing '->'!\n"); | ||
184 | 1870 | return 1; | ||
185 | 1871 | } | ||
186 | 1872 | val= ptr + 2; | ||
187 | 1873 | while (*val && my_isspace(&my_charset_latin1, *val)) | ||
188 | 1874 | val++; | ||
189 | 1875 | |||
190 | 1876 | // Write \0 and skip blanks at the end of key | ||
191 | 1877 | *ptr-- = 0; | ||
192 | 1878 | while (my_isspace(&my_charset_latin1, *ptr) && ptr > argument) | ||
193 | 1879 | *ptr-- = 0; | ||
194 | 1880 | |||
195 | 1881 | if (!*key) | ||
196 | 1882 | { | ||
197 | 1883 | sql_print_error("Bad syntax in rewrite-db: empty db-from!\n"); | ||
198 | 1884 | return 1; | ||
199 | 1885 | } | ||
200 | 1886 | |||
201 | 1887 | // Skip blanks at the end of val | ||
202 | 1888 | ptr= val; | ||
203 | 1889 | while (*ptr && !my_isspace(&my_charset_latin1, *ptr) && *ptr != ',') | ||
204 | 1890 | ++ptr; | ||
205 | 1891 | |||
206 | 1892 | if (my_isspace(&my_charset_latin1, *ptr)) | ||
207 | 1893 | { | ||
208 | 1894 | *(ptr++)= 0; | ||
209 | 1895 | while (*ptr && *ptr != ',') | ||
210 | 1896 | { | ||
211 | 1897 | if (!my_isspace(&my_charset_latin1, *ptr)) { | ||
212 | 1898 | sql_print_error("Bad syntax in rewrite-db: db-to must contain db " | ||
213 | 1899 | "name without spaces!\n"); | ||
214 | 1900 | return 1; | ||
215 | 1901 | } | ||
216 | 1902 | ++ptr; | ||
217 | 1903 | } | ||
218 | 1904 | } | ||
219 | 1905 | |||
220 | 1906 | if (*ptr == ',') | ||
221 | 1907 | { | ||
222 | 1908 | if (!rewrite_db_obs_syn_warn) | ||
223 | 1909 | { | ||
224 | 1910 | warning("The comma-separated list of rewritings syntax is obsolete and " | ||
225 | 1911 | "discarded in 5.7\n"); | ||
226 | 1912 | rewrite_db_obs_syn_warn= true; | ||
227 | 1913 | } | ||
228 | 1914 | *(ptr++)= 0; | ||
229 | 1915 | } | ||
230 | 1916 | else | ||
231 | 1917 | *ptr= 0; | ||
232 | 1918 | |||
233 | 1919 | if (!*val) | ||
234 | 1920 | { | ||
235 | 1921 | sql_print_error("Bad syntax in rewrite-db: empty db-to!\n"); | ||
236 | 1922 | return 1; | ||
237 | 1923 | } | ||
238 | 1924 | |||
239 | 1925 | if (!binlog_filter && | ||
240 | 1926 | !(binlog_filter= new Rpl_filter)) | ||
241 | 1927 | { | ||
242 | 1928 | sql_print_error("Failed to create Rpl_filter\n"); | ||
243 | 1929 | return 1; | ||
244 | 1930 | } | ||
245 | 1931 | |||
246 | 1932 | binlog_filter->add_db_rewrite(key, val); | ||
247 | 1933 | } while (*ptr); | ||
248 | 1934 | break; | ||
249 | 1935 | } | ||
250 | 1776 | case 'v': | 1936 | case 'v': |
251 | 1777 | if (argument == disabled_my_option) | 1937 | if (argument == disabled_my_option) |
252 | 1778 | verbose= 0; | 1938 | verbose= 0; |
253 | 1779 | 1939 | ||
254 | === added file 'mysql-test/extra/rpl_tests/grep_pattern.inc' | |||
255 | --- mysql-test/extra/rpl_tests/grep_pattern.inc 1970-01-01 00:00:00 +0000 | |||
256 | +++ mysql-test/extra/rpl_tests/grep_pattern.inc 2014-02-15 00:30:14 +0000 | |||
257 | @@ -0,0 +1,22 @@ | |||
258 | 1 | # Please set GREP_FILE and GREP_PATTERN environment variables | ||
259 | 2 | # to work this file properly. | ||
260 | 3 | --perl | ||
261 | 4 | use strict; | ||
262 | 5 | my $file= $ENV{'GREP_FILE'} or die "grep file not set"; | ||
263 | 6 | my $pattern= $ENV{'GREP_PATTERN'} or die "pattern is not set"; | ||
264 | 7 | open(FILE, "$file") or die("Unable to open $file: $!\n"); | ||
265 | 8 | my $count = 0; | ||
266 | 9 | print "Matching lines are:\n"; | ||
267 | 10 | while (<FILE>) { | ||
268 | 11 | my $line = $_; | ||
269 | 12 | if ($line =~ /$pattern/) { | ||
270 | 13 | print "$line\n"; | ||
271 | 14 | $count++; | ||
272 | 15 | } | ||
273 | 16 | } | ||
274 | 17 | if ($count == 0) { | ||
275 | 18 | print "None\n"; | ||
276 | 19 | } | ||
277 | 20 | print "Occurrences of the $pattern in the input file : $count\n"; | ||
278 | 21 | close(FILE); | ||
279 | 22 | EOF | ||
280 | 0 | 23 | ||
281 | === added file 'mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result' | |||
282 | --- mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result 1970-01-01 00:00:00 +0000 | |||
283 | +++ mysql-test/suite/binlog/r/binlog_mysqlbinlog_rewrite_db.result 2014-02-15 00:30:14 +0000 | |||
284 | @@ -0,0 +1,33 @@ | |||
285 | 1 | RESET MASTER; | ||
286 | 2 | CREATE DATABASE db1; | ||
287 | 3 | USE db1; | ||
288 | 4 | CREATE TABLE t1 (i INT); | ||
289 | 5 | INSERT INTO t1 VALUES(1); | ||
290 | 6 | INSERT INTO t1 VALUES(2); | ||
291 | 7 | UPDATE t1 SET i= i+1; | ||
292 | 8 | DELETE FROM t1 WHERE i=2; | ||
293 | 9 | [Syntax error in the use of the new option: The from database name is missing] | ||
294 | 10 | [Syntax error in the use of the new option: The '->' is missing] | ||
295 | 11 | [Syntax error in the use of the new option: The to database name is missing] | ||
296 | 12 | [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 1] | ||
297 | 13 | [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4,db5->db6"] | ||
298 | 14 | [log_grep.inc] file: mysqltest.log pattern: The comma-separated list of rewritings syntax is obsolete and discarded | ||
299 | 15 | [log_grep.inc] lines: 1 | ||
300 | 16 | [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 2] | ||
301 | 17 | [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4" --rewrite-db="db5->db6,db6->db7"] | ||
302 | 18 | [log_grep.inc] file: mysqltest.log pattern: The comma-separated list of rewritings syntax is obsolete and discarded | ||
303 | 19 | [log_grep.inc] lines: 2 | ||
304 | 20 | [VALID SYNTAX,The from->to database names are correctly mentioned] | ||
305 | 21 | #Dropping the database db1 and creating the table in the new database db2. | ||
306 | 22 | CREATE DATABASE db2; | ||
307 | 23 | DROP DATABASE db1; | ||
308 | 24 | RESET MASTER; | ||
309 | 25 | SELECT * FROM db2.t1; | ||
310 | 26 | ERROR 42S02: Table 'db2.t1' doesn't exist | ||
311 | 27 | DROP DATABASE db1; | ||
312 | 28 | RESET MASTER; | ||
313 | 29 | [The event of table db1.t1 has been successfully applied to db2.t1] | ||
314 | 30 | include/assert.inc [Assert that table db2.t1 has one row after applying the sql file.] | ||
315 | 31 | CLEANUP | ||
316 | 32 | DROP DATABASE db1; | ||
317 | 33 | DROP DATABASE db2; | ||
318 | 0 | 34 | ||
319 | === added file 'mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result' | |||
320 | --- mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result 1970-01-01 00:00:00 +0000 | |||
321 | +++ mysql-test/suite/binlog/r/binlog_rewrite_db_noleak.result 2014-02-15 00:30:14 +0000 | |||
322 | @@ -0,0 +1,29 @@ | |||
323 | 1 | RESET MASTER; | ||
324 | 2 | CREATE DATABASE db1; | ||
325 | 3 | USE db1; | ||
326 | 4 | CREATE TABLE t1 (i INT); | ||
327 | 5 | INSERT INTO db1.t1 VALUES(1); | ||
328 | 6 | INSERT INTO db1.t1 VALUES(2); | ||
329 | 7 | UPDATE t1 SET i= i+1; | ||
330 | 8 | DELETE FROM t1 WHERE i=2; | ||
331 | 9 | CREATE DATABASE db2; | ||
332 | 10 | CREATE TABLE db2.t1 (i INT); | ||
333 | 11 | INSERT INTO db2.t1 VALUES(3); | ||
334 | 12 | INSERT INTO db2.t1 VALUES(4); | ||
335 | 13 | INSERT INTO db2.t1 VALUES(5); | ||
336 | 14 | UPDATE db2.t1 SET i= i+1; | ||
337 | 15 | DELETE FROM db2.t1 WHERE i=4; | ||
338 | 16 | call mtr.add_suppression("Slave SQL: Error executing row event:*"); | ||
339 | 17 | Dropping the database db1 creating the new database db3. | ||
340 | 18 | DROP DATABASE db1; | ||
341 | 19 | CREATE DATABASE db3; | ||
342 | 20 | DROP DATABASE db2; | ||
343 | 21 | RESET MASTER; | ||
344 | 22 | [The sql file will be applied on the current database] | ||
345 | 23 | [The content of table db3.t1 and db2.t1 will be different confirming no leak] | ||
346 | 24 | include/assert.inc [The content of the table t1 in database db3 and db2 is different] | ||
347 | 25 | include/assert.inc [Table t1 in db3 have different row count than t1 in db2] | ||
348 | 26 | CLEANUP | ||
349 | 27 | DROP DATABASE db1; | ||
350 | 28 | DROP DATABASE db2; | ||
351 | 29 | DROP DATABASE db3; | ||
352 | 0 | 30 | ||
353 | === added file 'mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result' | |||
354 | --- mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result 1970-01-01 00:00:00 +0000 | |||
355 | +++ mysql-test/suite/binlog/r/binlog_rewrite_suppress_use.result 2014-02-15 00:30:14 +0000 | |||
356 | @@ -0,0 +1,29 @@ | |||
357 | 1 | RESET MASTER; | ||
358 | 2 | CREATE DATABASE db1; | ||
359 | 3 | USE db1; | ||
360 | 4 | CREATE TABLE t1 (i INT); | ||
361 | 5 | INSERT INTO t1 VALUES(1); | ||
362 | 6 | INSERT INTO t1 VALUES(2); | ||
363 | 7 | UPDATE t1 SET i= i+1; | ||
364 | 8 | DELETE FROM t1 WHERE i=2; | ||
365 | 9 | [The use <db_name> is not suppressed in the general use of mysqlbinlog] | ||
366 | 10 | Matching lines are: | ||
367 | 11 | use `db1`/*!*/; | ||
368 | 12 | |||
369 | 13 | Occurrences of the use `db1` in the input file : 1 | ||
370 | 14 | [The use <db_name> is suppressed on using rewrite-db option of mysqlbinlog] | ||
371 | 15 | Matching lines are: | ||
372 | 16 | None | ||
373 | 17 | Occurrences of the use `db1` in the input file : 0 | ||
374 | 18 | CREATE DATABASE db2; | ||
375 | 19 | DROP DATABASE db1; | ||
376 | 20 | RESET MASTER; | ||
377 | 21 | SELECT * FROM db2.t1; | ||
378 | 22 | ERROR 42S02: Table 'db2.t1' doesn't exist | ||
379 | 23 | DROP DATABASE db1; | ||
380 | 24 | RESET MASTER; | ||
381 | 25 | [The event of table db1.t1 has been successfully applied to db2.t1] | ||
382 | 26 | include/assert.inc [Assert that table db2.t1 has no rows after applying the sql file.] | ||
383 | 27 | [CLEANUP] | ||
384 | 28 | DROP DATABASE db1; | ||
385 | 29 | DROP DATABASE db2; | ||
386 | 0 | 30 | ||
387 | === added file 'mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result' | |||
388 | --- mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result 1970-01-01 00:00:00 +0000 | |||
389 | +++ mysql-test/suite/binlog/r/percona_mysqlbinlog_rewritedb.result 2014-02-15 00:30:14 +0000 | |||
390 | @@ -0,0 +1,152 @@ | |||
391 | 1 | # | ||
392 | 2 | # Apply log with '' | ||
393 | 3 | # | ||
394 | 4 | # use a | ||
395 | 5 | f | ||
396 | 6 | 0 | ||
397 | 7 | 0 | ||
398 | 8 | # use bbbbbbbbbbbbbbbbbbbb | ||
399 | 9 | f | ||
400 | 10 | 1 | ||
401 | 11 | 1 | ||
402 | 12 | # use cccccccccccccccc | ||
403 | 13 | f | ||
404 | 14 | 2 | ||
405 | 15 | 2 | ||
406 | 16 | # use d | ||
407 | 17 | f | ||
408 | 18 | # | ||
409 | 19 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="d"' | ||
410 | 20 | # | ||
411 | 21 | # use a | ||
412 | 22 | f | ||
413 | 23 | # use bbbbbbbbbbbbbbbbbbbb | ||
414 | 24 | f | ||
415 | 25 | # use cccccccccccccccc | ||
416 | 26 | f | ||
417 | 27 | # use d | ||
418 | 28 | f | ||
419 | 29 | 2 | ||
420 | 30 | 2 | ||
421 | 31 | # | ||
422 | 32 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="cccccccccccccccc"' | ||
423 | 33 | # | ||
424 | 34 | # use a | ||
425 | 35 | f | ||
426 | 36 | # use bbbbbbbbbbbbbbbbbbbb | ||
427 | 37 | f | ||
428 | 38 | # use cccccccccccccccc | ||
429 | 39 | f | ||
430 | 40 | # use d | ||
431 | 41 | f | ||
432 | 42 | # | ||
433 | 43 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="bbbbbbbbbbbbbbbbbbbb"' | ||
434 | 44 | # | ||
435 | 45 | # use a | ||
436 | 46 | f | ||
437 | 47 | # use bbbbbbbbbbbbbbbbbbbb | ||
438 | 48 | f | ||
439 | 49 | 0 | ||
440 | 50 | 0 | ||
441 | 51 | 1 | ||
442 | 52 | 1 | ||
443 | 53 | # use cccccccccccccccc | ||
444 | 54 | f | ||
445 | 55 | # use d | ||
446 | 56 | f | ||
447 | 57 | # | ||
448 | 58 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d" --database="a"' | ||
449 | 59 | # | ||
450 | 60 | # use a | ||
451 | 61 | f | ||
452 | 62 | # use bbbbbbbbbbbbbbbbbbbb | ||
453 | 63 | f | ||
454 | 64 | # use cccccccccccccccc | ||
455 | 65 | f | ||
456 | 66 | # use d | ||
457 | 67 | f | ||
458 | 68 | # | ||
459 | 69 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb" --rewrite-db="cccccccccccccccc->d"' | ||
460 | 70 | # | ||
461 | 71 | # use a | ||
462 | 72 | f | ||
463 | 73 | # use bbbbbbbbbbbbbbbbbbbb | ||
464 | 74 | f | ||
465 | 75 | 0 | ||
466 | 76 | 0 | ||
467 | 77 | 1 | ||
468 | 78 | 1 | ||
469 | 79 | # use cccccccccccccccc | ||
470 | 80 | f | ||
471 | 81 | # use d | ||
472 | 82 | f | ||
473 | 83 | 2 | ||
474 | 84 | 2 | ||
475 | 85 | # | ||
476 | 86 | # Apply log with '--rewrite-db=" a -> bbbbbbbbbbbbbbbbbbbb , cccccccccccccccc -> d "' | ||
477 | 87 | # | ||
478 | 88 | # use a | ||
479 | 89 | f | ||
480 | 90 | # use bbbbbbbbbbbbbbbbbbbb | ||
481 | 91 | f | ||
482 | 92 | 0 | ||
483 | 93 | 0 | ||
484 | 94 | 1 | ||
485 | 95 | 1 | ||
486 | 96 | # use cccccccccccccccc | ||
487 | 97 | f | ||
488 | 98 | # use d | ||
489 | 99 | f | ||
490 | 100 | 2 | ||
491 | 101 | 2 | ||
492 | 102 | # | ||
493 | 103 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb,cccccccccccccccc->d"' | ||
494 | 104 | # | ||
495 | 105 | # use a | ||
496 | 106 | f | ||
497 | 107 | # use bbbbbbbbbbbbbbbbbbbb | ||
498 | 108 | f | ||
499 | 109 | 0 | ||
500 | 110 | 0 | ||
501 | 111 | 1 | ||
502 | 112 | 1 | ||
503 | 113 | # use cccccccccccccccc | ||
504 | 114 | f | ||
505 | 115 | # use d | ||
506 | 116 | f | ||
507 | 117 | 2 | ||
508 | 118 | 2 | ||
509 | 119 | # | ||
510 | 120 | # Apply log with '--rewrite-db="a->d"' | ||
511 | 121 | # | ||
512 | 122 | # use a | ||
513 | 123 | f | ||
514 | 124 | # use bbbbbbbbbbbbbbbbbbbb | ||
515 | 125 | f | ||
516 | 126 | 1 | ||
517 | 127 | 1 | ||
518 | 128 | # use cccccccccccccccc | ||
519 | 129 | f | ||
520 | 130 | 2 | ||
521 | 131 | 2 | ||
522 | 132 | # use d | ||
523 | 133 | f | ||
524 | 134 | 0 | ||
525 | 135 | 0 | ||
526 | 136 | # | ||
527 | 137 | # Apply log with '--rewrite-db="a->bbbbbbbbbbbbbbbbbbbb"' | ||
528 | 138 | # | ||
529 | 139 | # use a | ||
530 | 140 | f | ||
531 | 141 | # use bbbbbbbbbbbbbbbbbbbb | ||
532 | 142 | f | ||
533 | 143 | 0 | ||
534 | 144 | 0 | ||
535 | 145 | 1 | ||
536 | 146 | 1 | ||
537 | 147 | # use cccccccccccccccc | ||
538 | 148 | f | ||
539 | 149 | 2 | ||
540 | 150 | 2 | ||
541 | 151 | # use d | ||
542 | 152 | f | ||
543 | 0 | 153 | ||
544 | === added file 'mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test' | |||
545 | --- mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test 1970-01-01 00:00:00 +0000 | |||
546 | +++ mysql-test/suite/binlog/t/binlog_mysqlbinlog_rewrite_db.test 2014-02-15 00:30:14 +0000 | |||
547 | @@ -0,0 +1,95 @@ | |||
548 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
549 | 2 | # | ||
550 | 3 | # The test checks the new rewrite-db option for the mysqlbinlog. | ||
551 | 4 | # | ||
552 | 5 | # The test checks the following aspects of the new option: | ||
553 | 6 | |||
554 | 7 | # 1. The valid syntax for the use of the new option and the errors in | ||
555 | 8 | # case the usage is not correct. | ||
556 | 9 | # 2. Apply the new binlog file ( with database rewritten ) to a new database | ||
557 | 10 | # and check if it works. | ||
558 | 11 | # | ||
559 | 12 | --source include/have_binlog_format_row.inc | ||
560 | 13 | |||
561 | 14 | RESET MASTER; | ||
562 | 15 | CREATE DATABASE db1; | ||
563 | 16 | USE db1; | ||
564 | 17 | CREATE TABLE t1 (i INT); | ||
565 | 18 | |||
566 | 19 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
567 | 20 | INSERT INTO t1 VALUES(1); | ||
568 | 21 | INSERT INTO t1 VALUES(2); | ||
569 | 22 | UPDATE t1 SET i= i+1; | ||
570 | 23 | DELETE FROM t1 WHERE i=2; | ||
571 | 24 | |||
572 | 25 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
573 | 26 | --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
574 | 27 | |||
575 | 28 | # Using the new option to apply the row event on some other database (from db1 -> db2 in the current case) | ||
576 | 29 | |||
577 | 30 | --echo [Syntax error in the use of the new option: The from database name is missing] | ||
578 | 31 | --error 1 | ||
579 | 32 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
580 | 33 | |||
581 | 34 | --echo [Syntax error in the use of the new option: The '->' is missing] | ||
582 | 35 | --error 1 | ||
583 | 36 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1 db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
584 | 37 | |||
585 | 38 | --echo [Syntax error in the use of the new option: The to database name is missing] | ||
586 | 39 | --error 1 | ||
587 | 40 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
588 | 41 | |||
589 | 42 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 1] | ||
590 | 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 | ||
591 | 44 | |||
592 | 45 | --echo [Test that warning about obsolete syntax is shown only once for --rewrite-db="db1->db2,db3->db4,db5->db6"] | ||
593 | 46 | --let log_file=mysqltest.log | ||
594 | 47 | --let log_file_full_path=$MYSQLTEST_VARDIR/log/current_test | ||
595 | 48 | --let grep_pattern=The comma-separated list of rewritings syntax is obsolete and discarded | ||
596 | 49 | --source include/log_grep.inc | ||
597 | 50 | |||
598 | 51 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned, but there is obsolete syntax warning 2] | ||
599 | 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 | ||
600 | 53 | |||
601 | 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"] | ||
602 | 55 | --let log_file=mysqltest.log | ||
603 | 56 | --let log_file_full_path=$MYSQLTEST_VARDIR/log/current_test | ||
604 | 57 | --let grep_pattern=The comma-separated list of rewritings syntax is obsolete and discarded | ||
605 | 58 | --source include/log_grep.inc | ||
606 | 59 | |||
607 | 60 | --echo [VALID SYNTAX,The from->to database names are correctly mentioned] | ||
608 | 61 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
609 | 62 | |||
610 | 63 | --echo #Dropping the database db1 and creating the table in the new database db2. | ||
611 | 64 | |||
612 | 65 | CREATE DATABASE db2; | ||
613 | 66 | DROP DATABASE db1; | ||
614 | 67 | |||
615 | 68 | # The SQL file will be applied but nothing is applied on Database db2 since the row event was | ||
616 | 69 | # generated for database db1 and table t1. | ||
617 | 70 | |||
618 | 71 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
619 | 72 | # replayed through mysqlbinlog will be skipped. | ||
620 | 73 | RESET MASTER; | ||
621 | 74 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
622 | 75 | --error ER_NO_SUCH_TABLE | ||
623 | 76 | SELECT * FROM db2.t1; | ||
624 | 77 | |||
625 | 78 | # The SQL file should be applied since the row event was extracted using the new mysqlbinlog option. | ||
626 | 79 | |||
627 | 80 | DROP DATABASE db1; | ||
628 | 81 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
629 | 82 | # replayed through mysqlbinlog will be skipped. | ||
630 | 83 | RESET MASTER; | ||
631 | 84 | --echo [The event of table db1.t1 has been successfully applied to db2.t1] | ||
632 | 85 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
633 | 86 | --let $assert_text= Assert that table db2.t1 has one row after applying the sql file. | ||
634 | 87 | --let $assert_cond= `SELECT COUNT(*)=1 from db2.t1` | ||
635 | 88 | --source include/assert.inc | ||
636 | 89 | |||
637 | 90 | --echo CLEANUP | ||
638 | 91 | |||
639 | 92 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
640 | 93 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
641 | 94 | DROP DATABASE db1; | ||
642 | 95 | DROP DATABASE db2; | ||
643 | 0 | 96 | ||
644 | === added file 'mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test' | |||
645 | --- mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test 1970-01-01 00:00:00 +0000 | |||
646 | +++ mysql-test/suite/binlog/t/binlog_rewrite_db_noleak.test 2014-02-15 00:30:14 +0000 | |||
647 | @@ -0,0 +1,79 @@ | |||
648 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
649 | 2 | # | ||
650 | 3 | # The test checks that there is no leak of the global variables used | ||
651 | 4 | # to decide whether rewrite-db option is ON or OFF. | ||
652 | 5 | # | ||
653 | 6 | # The test checks this by creating two tables in two different databases. | ||
654 | 7 | # insert rows in both of them. | ||
655 | 8 | # | ||
656 | 9 | # Read the binlog file using the new option --rewrite-db="db1->db3" and | ||
657 | 10 | # writing in the .sql file. | ||
658 | 11 | # | ||
659 | 12 | # On applying the .sql file on database db3, we get an error since not | ||
660 | 13 | # all events are converted for database db3. Only DB1 is converted to db3. | ||
661 | 14 | # The db2 event cause the error. | ||
662 | 15 | # | ||
663 | 16 | |||
664 | 17 | --source include/have_binlog_format_row.inc | ||
665 | 18 | RESET MASTER; | ||
666 | 19 | CREATE DATABASE db1; | ||
667 | 20 | USE db1; | ||
668 | 21 | CREATE TABLE t1 (i INT); | ||
669 | 22 | |||
670 | 23 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
671 | 24 | INSERT INTO db1.t1 VALUES(1); | ||
672 | 25 | INSERT INTO db1.t1 VALUES(2); | ||
673 | 26 | UPDATE t1 SET i= i+1; | ||
674 | 27 | DELETE FROM t1 WHERE i=2; | ||
675 | 28 | |||
676 | 29 | CREATE DATABASE db2; | ||
677 | 30 | CREATE TABLE db2.t1 (i INT); | ||
678 | 31 | |||
679 | 32 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
680 | 33 | INSERT INTO db2.t1 VALUES(3); | ||
681 | 34 | INSERT INTO db2.t1 VALUES(4); | ||
682 | 35 | INSERT INTO db2.t1 VALUES(5); | ||
683 | 36 | UPDATE db2.t1 SET i= i+1; | ||
684 | 37 | DELETE FROM db2.t1 WHERE i=4; | ||
685 | 38 | |||
686 | 39 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
687 | 40 | |||
688 | 41 | # Using the new option to apply the row event on some other database (from db1 -> db3 in the current case) | ||
689 | 42 | |||
690 | 43 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db3" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
691 | 44 | call mtr.add_suppression("Slave SQL: Error executing row event:*"); | ||
692 | 45 | |||
693 | 46 | --echo Dropping the database db1 creating the new database db3. | ||
694 | 47 | DROP DATABASE db1; | ||
695 | 48 | CREATE DATABASE db3; | ||
696 | 49 | |||
697 | 50 | # The SQL file will be applied but only db1 events will be replayed on db3. | ||
698 | 51 | # Database db2 will not be applied on db3 confirming there is no leak. | ||
699 | 52 | DROP DATABASE db2; | ||
700 | 53 | |||
701 | 54 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
702 | 55 | # replayed through mysqlbinlog will be skipped. | ||
703 | 56 | RESET MASTER; | ||
704 | 57 | --echo [The sql file will be applied on the current database] | ||
705 | 58 | --exec $MYSQL --database=db3 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
706 | 59 | |||
707 | 60 | --echo [The content of table db3.t1 and db2.t1 will be different confirming no leak] | ||
708 | 61 | |||
709 | 62 | --let $db3_max= `SELECT MAX(i) FROM db3.t1` | ||
710 | 63 | --let $db2_max= `SELECT MAX(i) FROM db2.t1` | ||
711 | 64 | --let $assert_text= The content of the table t1 in database db3 and db2 is different | ||
712 | 65 | --let $assert_cond= $db3_max <> $db2_max | ||
713 | 66 | --source include/assert.inc | ||
714 | 67 | |||
715 | 68 | --let $db3_count= `SELECT COUNT(*) FROM db3.t1` | ||
716 | 69 | --let $db2_count= `SELECT COUNT(*) FROM db2.t1` | ||
717 | 70 | --let $assert_text= Table t1 in db3 have different row count than t1 in db2 | ||
718 | 71 | --let $assert_cond= $db3_count=1 AND $db2_count<>1 | ||
719 | 72 | --source include/assert.inc | ||
720 | 73 | |||
721 | 74 | --echo CLEANUP | ||
722 | 75 | |||
723 | 76 | #--remove_file $MYSQLTEST_VARDIR/tmp/rewrite_noleak.sql | ||
724 | 77 | DROP DATABASE db1; | ||
725 | 78 | DROP DATABASE db2; | ||
726 | 79 | DROP DATABASE db3; | ||
727 | 0 | 80 | ||
728 | === added file 'mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test' | |||
729 | --- mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test 1970-01-01 00:00:00 +0000 | |||
730 | +++ mysql-test/suite/binlog/t/binlog_rewrite_suppress_use.test 2014-02-15 00:30:14 +0000 | |||
731 | @@ -0,0 +1,61 @@ | |||
732 | 1 | # WL#6404 - Add rewrite-db option to mysqlbinlog on RBR | ||
733 | 2 | # | ||
734 | 3 | # The test aims to check that the use of rewrite-db option of | ||
735 | 4 | # mysqlbinlog suppresses the USE DATABASE command logged in | ||
736 | 5 | # binlog file. | ||
737 | 6 | # | ||
738 | 7 | |||
739 | 8 | --source include/have_binlog_format_row.inc | ||
740 | 9 | RESET MASTER; | ||
741 | 10 | CREATE DATABASE db1; | ||
742 | 11 | USE db1; | ||
743 | 12 | CREATE TABLE t1 (i INT); | ||
744 | 13 | |||
745 | 14 | # Get some INSERT, UPDATE and DELETE ROW events. | ||
746 | 15 | INSERT INTO t1 VALUES(1); | ||
747 | 16 | INSERT INTO t1 VALUES(2); | ||
748 | 17 | UPDATE t1 SET i= i+1; | ||
749 | 18 | DELETE FROM t1 WHERE i=2; | ||
750 | 19 | |||
751 | 20 | --let $MYSQLD_DATADIR= `select @@datadir` | ||
752 | 21 | |||
753 | 22 | # Checking for the suppression of the USE DATABASE command on using the new option. | ||
754 | 23 | # Reading binlog file without the rewrite-db option. | ||
755 | 24 | --echo [The use <db_name> is not suppressed in the general use of mysqlbinlog] | ||
756 | 25 | --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
757 | 26 | --let GREP_FILE=$MYSQLTEST_VARDIR/tmp/row_event.sql | ||
758 | 27 | --let GREP_PATTERN=use `db1` | ||
759 | 28 | --source extra/rpl_tests/grep_pattern.inc | ||
760 | 29 | |||
761 | 30 | # Reading binlog file with the rewrite-db option. | ||
762 | 31 | --echo [The use <db_name> is suppressed on using rewrite-db option of mysqlbinlog] | ||
763 | 32 | --exec $MYSQL_BINLOG --force-if-open --rewrite-db="db1->db2" $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
764 | 33 | --let GREP_FILE=$MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
765 | 34 | --let GREP_PATTERN=use `db1` | ||
766 | 35 | --source extra/rpl_tests/grep_pattern.inc | ||
767 | 36 | |||
768 | 37 | CREATE DATABASE db2; | ||
769 | 38 | DROP DATABASE db1; | ||
770 | 39 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
771 | 40 | # replayed through mysqlbinlog will be skipped. | ||
772 | 41 | RESET MASTER; | ||
773 | 42 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
774 | 43 | --error ER_NO_SUCH_TABLE | ||
775 | 44 | SELECT * FROM db2.t1; | ||
776 | 45 | |||
777 | 46 | DROP DATABASE db1; | ||
778 | 47 | # With gtid-mode=on we need purge gtid_executed, if not transactions | ||
779 | 48 | # replayed through mysqlbinlog will be skipped. | ||
780 | 49 | RESET MASTER; | ||
781 | 50 | --echo [The event of table db1.t1 has been successfully applied to db2.t1] | ||
782 | 51 | --exec $MYSQL --database=db2 --local-infile=1 < $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
783 | 52 | --let $assert_text= Assert that table db2.t1 has no rows after applying the sql file. | ||
784 | 53 | --let $assert_cond= `SELECT COUNT(*)=1 from db2.t1` | ||
785 | 54 | --source include/assert.inc | ||
786 | 55 | |||
787 | 56 | --echo [CLEANUP] | ||
788 | 57 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event.sql | ||
789 | 58 | --remove_file $MYSQLTEST_VARDIR/tmp/row_event_rewrite.sql | ||
790 | 59 | |||
791 | 60 | DROP DATABASE db1; | ||
792 | 61 | DROP DATABASE db2; | ||
793 | 0 | 62 | ||
794 | === added file 'mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt' | |||
795 | --- mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt 1970-01-01 00:00:00 +0000 | |||
796 | +++ mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb-master.opt 2014-02-15 00:30:14 +0000 | |||
797 | @@ -0,0 +1,1 @@ | |||
798 | 1 | --local-infile=1 | ||
799 | 0 | 2 | ||
800 | === added file 'mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test' | |||
801 | --- mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test 1970-01-01 00:00:00 +0000 | |||
802 | +++ mysql-test/suite/binlog/t/percona_mysqlbinlog_rewritedb.test 2014-02-15 00:30:14 +0000 | |||
803 | @@ -0,0 +1,80 @@ | |||
804 | 1 | --source include/have_log_bin.inc | ||
805 | 2 | # | ||
806 | 3 | # WL #36: http://askmonty.org/worklog/Server-Sprint/?tid=36 | ||
807 | 4 | # This is basic test for --rewrite-db option. | ||
808 | 5 | # mysqlbinlog --rewrite-db="from->to" should rewrite database name | ||
809 | 6 | # | ||
810 | 7 | |||
811 | 8 | --disable_query_log | ||
812 | 9 | |||
813 | 10 | # Because RBR event DB rewrite requires shifting of | ||
814 | 11 | # Table_map_log_event contents around if the DB name length | ||
815 | 12 | # changes, this case is tested for both shorter and longer | ||
816 | 13 | # names. | ||
817 | 14 | |||
818 | 15 | --let DB1=a | ||
819 | 16 | --let DB2=bbbbbbbbbbbbbbbbbbbb | ||
820 | 17 | --let DB3=cccccccccccccccc | ||
821 | 18 | --let DB4=d | ||
822 | 19 | |||
823 | 20 | eval CREATE DATABASE $DB1; eval USE $DB1; CREATE TABLE t1(f INT); | ||
824 | 21 | eval CREATE DATABASE $DB2; eval USE $DB2; CREATE TABLE t1(f INT); | ||
825 | 22 | eval CREATE DATABASE $DB3; eval USE $DB3; CREATE TABLE t1(f INT); | ||
826 | 23 | eval CREATE DATABASE $DB4; eval USE $DB4; CREATE TABLE t1(f INT); | ||
827 | 24 | |||
828 | 25 | RESET MASTER; | ||
829 | 26 | --let MYSQLD_DATA_DIR=`select @@datadir` | ||
830 | 27 | --let LOAD_DATA_FILE=$MYSQLD_DATA_DIR/table.values | ||
831 | 28 | --let BIN_LOG_FILE_NAME=query_get_value(show master status, File, 1) | ||
832 | 29 | --let BIN_LOG_START_POSITION=query_get_value(show master status, Position, 1) | ||
833 | 30 | eval USE $DB1; INSERT INTO t1 VALUES(0); INSERT INTO t1 VALUES(0); | ||
834 | 31 | eval USE $DB2; INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1); | ||
835 | 32 | write_file $LOAD_DATA_FILE; | ||
836 | 33 | 2 | ||
837 | 34 | 2 | ||
838 | 35 | EOF | ||
839 | 36 | eval USE $DB3; | ||
840 | 37 | --eval LOAD DATA INFILE "$LOAD_DATA_FILE" INTO TABLE t1 | ||
841 | 38 | --let BIN_LOG_STOP_POSITION=query_get_value(show master status, Position, 1) | ||
842 | 39 | FLUSH LOGS; | ||
843 | 40 | |||
844 | 41 | --let BIN_LOG_FULL_PATH=`SELECT CONCAT("$MYSQLD_DATA_DIR", "$BIN_LOG_FILE_NAME")` | ||
845 | 42 | |||
846 | 43 | --let i=10 | ||
847 | 44 | |||
848 | 45 | while ($i) | ||
849 | 46 | { | ||
850 | 47 | # Test for different combinations of syntax and db name filtering and rewriting | ||
851 | 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` | ||
852 | 49 | |||
853 | 50 | eval USE $DB1; DELETE FROM t1; | ||
854 | 51 | eval USE $DB2; DELETE FROM t1; | ||
855 | 52 | eval USE $DB3; DELETE FROM t1; | ||
856 | 53 | eval USE $DB4; DELETE FROM t1; | ||
857 | 54 | |||
858 | 55 | --echo # | ||
859 | 56 | --echo # Apply log with '$REWRITE' | ||
860 | 57 | --echo # | ||
861 | 58 | |||
862 | 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 | ||
863 | 60 | |||
864 | 61 | --echo # use $DB1 | ||
865 | 62 | eval USE $DB1; SELECT * FROM t1 ORDER BY f; | ||
866 | 63 | --echo # use $DB2 | ||
867 | 64 | eval USE $DB2; SELECT * FROM t1 ORDER BY f; | ||
868 | 65 | --echo # use $DB3 | ||
869 | 66 | eval USE $DB3; SELECT * FROM t1 ORDER BY f; | ||
870 | 67 | --echo # use $DB4 | ||
871 | 68 | eval USE $DB4; SELECT * FROM t1 ORDER BY f; | ||
872 | 69 | |||
873 | 70 | dec $i; | ||
874 | 71 | } | ||
875 | 72 | |||
876 | 73 | eval USE $DB1; DROP TABLE t1; eval DROP DATABASE $DB1; | ||
877 | 74 | eval USE $DB2; DROP TABLE t1; eval DROP DATABASE $DB2; | ||
878 | 75 | eval USE $DB3; DROP TABLE t1; eval DROP DATABASE $DB3; | ||
879 | 76 | eval USE $DB4; DROP TABLE t1; eval DROP DATABASE $DB4; | ||
880 | 77 | |||
881 | 78 | --remove_file $LOAD_DATA_FILE | ||
882 | 79 | |||
883 | 80 | --enable_query_log | ||
884 | 0 | 81 | ||
885 | === modified file 'sql/log_event.cc' | |||
886 | --- sql/log_event.cc 2013-12-16 08:45:31 +0000 | |||
887 | +++ sql/log_event.cc 2014-02-15 00:30:14 +0000 | |||
888 | @@ -11862,6 +11862,108 @@ | |||
889 | 11862 | my_free(m_memory); | 11862 | my_free(m_memory); |
890 | 11863 | } | 11863 | } |
891 | 11864 | 11864 | ||
892 | 11865 | #ifdef MYSQL_CLIENT | ||
893 | 11866 | |||
894 | 11867 | /* | ||
895 | 11868 | Rewrite database name for the event to name specified by new_db | ||
896 | 11869 | SYNOPSIS | ||
897 | 11870 | new_db Database name to change to | ||
898 | 11871 | new_len Length | ||
899 | 11872 | desc Event describing binlog that we're writing to. | ||
900 | 11873 | |||
901 | 11874 | DESCRIPTION | ||
902 | 11875 | Reset db name. This function assumes that temp_buf member contains event | ||
903 | 11876 | representation taken from a binary log. It resets m_dbnam and m_dblen and | ||
904 | 11877 | rewrites temp_buf with new db name. | ||
905 | 11878 | |||
906 | 11879 | RETURN | ||
907 | 11880 | 0 - Success | ||
908 | 11881 | other - Error | ||
909 | 11882 | */ | ||
910 | 11883 | |||
911 | 11884 | int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len, | ||
912 | 11885 | const Format_description_log_event* desc) | ||
913 | 11886 | { | ||
914 | 11887 | DBUG_ENTER("Table_map_log_event::rewrite_db"); | ||
915 | 11888 | DBUG_ASSERT(temp_buf); | ||
916 | 11889 | |||
917 | 11890 | uint header_len= min((unsigned)desc->common_header_len, | ||
918 | 11891 | (unsigned)LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN; | ||
919 | 11892 | int len_diff; | ||
920 | 11893 | |||
921 | 11894 | if (!(len_diff= new_len - m_dblen)) | ||
922 | 11895 | { | ||
923 | 11896 | memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1); | ||
924 | 11897 | memcpy((void*) m_dbnam, new_db, m_dblen + 1); | ||
925 | 11898 | DBUG_RETURN(0); | ||
926 | 11899 | } | ||
927 | 11900 | |||
928 | 11901 | // Create new temp_buf | ||
929 | 11902 | ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET); | ||
930 | 11903 | ulong event_new_len= event_cur_len + len_diff; | ||
931 | 11904 | char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME)); | ||
932 | 11905 | |||
933 | 11906 | if (!new_temp_buf) | ||
934 | 11907 | { | ||
935 | 11908 | sql_print_error("Table_map_log_event::rewrite_db: " | ||
936 | 11909 | "failed to allocate new temp_buf (%d bytes required)", | ||
937 | 11910 | event_new_len); | ||
938 | 11911 | DBUG_RETURN(-1); | ||
939 | 11912 | } | ||
940 | 11913 | |||
941 | 11914 | // Rewrite temp_buf | ||
942 | 11915 | char* ptr= new_temp_buf; | ||
943 | 11916 | ulong cnt= 0; | ||
944 | 11917 | |||
945 | 11918 | // Copy header and change event length | ||
946 | 11919 | memcpy(ptr, temp_buf, header_len); | ||
947 | 11920 | int4store(ptr + EVENT_LEN_OFFSET, event_new_len); | ||
948 | 11921 | ptr += header_len; | ||
949 | 11922 | cnt += header_len; | ||
950 | 11923 | |||
951 | 11924 | // Write new db name length and new name | ||
952 | 11925 | *ptr++ = new_len; | ||
953 | 11926 | memcpy(ptr, new_db, new_len + 1); | ||
954 | 11927 | ptr += new_len + 1; | ||
955 | 11928 | cnt += m_dblen + 2; | ||
956 | 11929 | |||
957 | 11930 | // Copy rest part | ||
958 | 11931 | memcpy(ptr, temp_buf + cnt, event_cur_len - cnt); | ||
959 | 11932 | |||
960 | 11933 | // Reregister temp buf | ||
961 | 11934 | free_temp_buf(); | ||
962 | 11935 | register_temp_buf(new_temp_buf); | ||
963 | 11936 | |||
964 | 11937 | // Reset m_dbnam and m_dblen members | ||
965 | 11938 | m_dblen= new_len; | ||
966 | 11939 | |||
967 | 11940 | // m_dbnam resides in m_memory together with m_tblnam and m_coltype | ||
968 | 11941 | uchar* memory= m_memory; | ||
969 | 11942 | char const* tblnam= m_tblnam; | ||
970 | 11943 | uchar* coltype= m_coltype; | ||
971 | 11944 | |||
972 | 11945 | m_memory= (uchar*) my_multi_malloc(MYF(MY_WME), | ||
973 | 11946 | &m_dbnam, (uint) m_dblen + 1, | ||
974 | 11947 | &m_tblnam, (uint) m_tbllen + 1, | ||
975 | 11948 | &m_coltype, (uint) m_colcnt, | ||
976 | 11949 | NullS); | ||
977 | 11950 | |||
978 | 11951 | if (!m_memory) | ||
979 | 11952 | { | ||
980 | 11953 | sql_print_error("Table_map_log_event::rewrite_db: " | ||
981 | 11954 | "failed to allocate new m_memory (%d + %d + %d bytes required)", | ||
982 | 11955 | m_dblen + 1, m_tbllen + 1, m_colcnt); | ||
983 | 11956 | DBUG_RETURN(-1); | ||
984 | 11957 | } | ||
985 | 11958 | |||
986 | 11959 | memcpy((void*)m_dbnam, new_db, m_dblen + 1); | ||
987 | 11960 | memcpy((void*)m_tblnam, tblnam, m_tbllen + 1); | ||
988 | 11961 | memcpy(m_coltype, coltype, m_colcnt); | ||
989 | 11962 | |||
990 | 11963 | my_free(memory); | ||
991 | 11964 | DBUG_RETURN(0); | ||
992 | 11965 | } | ||
993 | 11966 | #endif /* MYSQL_CLIENT */ | ||
994 | 11865 | /* | 11967 | /* |
995 | 11866 | Return value is an error code, one of: | 11968 | Return value is an error code, one of: |
996 | 11867 | 11969 | ||
997 | 11868 | 11970 | ||
998 | === modified file 'sql/log_event.h' | |||
999 | --- sql/log_event.h 2013-10-23 08:48:28 +0000 | |||
1000 | +++ sql/log_event.h 2014-02-15 00:30:14 +0000 | |||
1001 | @@ -3861,7 +3861,10 @@ | |||
1002 | 3861 | const Table_id& get_table_id() const { return m_table_id; } | 3861 | const Table_id& get_table_id() const { return m_table_id; } |
1003 | 3862 | const char *get_table_name() const { return m_tblnam; } | 3862 | const char *get_table_name() const { return m_tblnam; } |
1004 | 3863 | const char *get_db_name() const { return m_dbnam; } | 3863 | const char *get_db_name() const { return m_dbnam; } |
1006 | 3864 | 3864 | #ifdef MYSQL_CLIENT | |
1007 | 3865 | int rewrite_db(const char* new_name, size_t new_name_len, | ||
1008 | 3866 | const Format_description_log_event*); | ||
1009 | 3867 | #endif | ||
1010 | 3865 | virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } | 3868 | virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } |
1011 | 3866 | virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } | 3869 | virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } |
1012 | 3867 | 3870 |
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.