1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysql_priv.h"
17
#include "rpl_filter.h"
19
#define TABLE_RULE_HASH_SIZE 16
20
#define TABLE_RULE_ARR_SIZE 16
22
Rpl_filter::Rpl_filter() :
23
table_rules_on(0), do_table_inited(0), ignore_table_inited(0),
24
wild_do_table_inited(0), wild_ignore_table_inited(0)
32
Rpl_filter::~Rpl_filter()
36
if (ignore_table_inited)
37
hash_free(&ignore_table);
38
if (wild_do_table_inited)
39
free_string_array(&wild_do_table);
40
if (wild_ignore_table_inited)
41
free_string_array(&wild_ignore_table);
43
free_list(&ignore_db);
44
free_list(&rewrite_db);
49
Returns true if table should be logged/replicated
53
db db to use if db in TABLE_LIST is undefined for a table
54
tables list of tables to check
57
Changing table order in the list can lead to different results.
59
Note also order of precedence of do/ignore rules (see code). For
60
that reason, users should not set conflicting rules because they
61
may get unpredicted results (precedence order is explained in the
64
If no table in the list is marked "updating", then we always
65
return 0, because there is no reason to execute this statement on
66
slave if it updates nothing. (Currently, this can only happen if
67
statement is a multi-delete (SQLCOM_DELETE_MULTI) and "tables" are
68
the tables in the FROM):
70
In the case of SQLCOM_DELETE_MULTI, there will be a second call to
71
tables_ok(), with tables having "updating==TRUE" (those after the
72
DELETE), so this second call will make the decision (because
73
all_tables_not_ok() = !tables_ok(1st_list) &&
74
!tables_ok(2nd_list)).
77
"Include all tables like "abc.%" except "%.EFG"". (Can't be done now.)
78
If we supported Perl regexps, we could do it with pattern: /^abc\.(?!EFG)/
79
(I could not find an equivalent in the regex library MySQL uses).
82
0 should not be logged/replicated
83
1 should be logged/replicated
87
Rpl_filter::tables_ok(const char* db, TABLE_LIST* tables)
89
bool some_tables_updating= 0;
90
DBUG_ENTER("Rpl_filter::tables_ok");
92
for (; tables; tables= tables->next_global)
94
char hash_key[2*NAME_LEN+2];
98
if (!tables->updating)
100
some_tables_updating= 1;
101
end= strmov(hash_key, tables->db ? tables->db : db);
103
len= (uint) (strmov(end, tables->table_name) - hash_key);
104
if (do_table_inited) // if there are any do's
106
if (hash_search(&do_table, (uchar*) hash_key, len))
109
if (ignore_table_inited) // if there are any ignores
111
if (hash_search(&ignore_table, (uchar*) hash_key, len))
114
if (wild_do_table_inited &&
115
find_wild(&wild_do_table, hash_key, len))
117
if (wild_ignore_table_inited &&
118
find_wild(&wild_ignore_table, hash_key, len))
123
If no table was to be updated, ignore statement (no reason we play it on
124
slave, slave is supposed to replicate _changes_ only).
125
If no explicit rule found and there was a do list, do not replicate.
126
If there was no do list, go ahead
128
DBUG_RETURN(some_tables_updating &&
129
!do_table_inited && !wild_do_table_inited);
134
Checks whether a db matches some do_db and ignore_db rules
138
db name of the db to check
141
0 should not be logged/replicated
142
1 should be logged/replicated
146
Rpl_filter::db_ok(const char* db)
148
DBUG_ENTER("Rpl_filter::db_ok");
150
if (do_db.is_empty() && ignore_db.is_empty())
151
DBUG_RETURN(1); // Ok to replicate if the user puts no constraints
154
If the user has specified restrictions on which databases to replicate
155
and db was not selected, do not replicate.
160
if (!do_db.is_empty()) // if the do's are not empty
162
I_List_iterator<i_string> it(do_db);
167
if (!strcmp(tmp->ptr, db))
168
DBUG_RETURN(1); // match
172
else // there are some elements in the don't, otherwise we cannot get here
174
I_List_iterator<i_string> it(ignore_db);
179
if (!strcmp(tmp->ptr, db))
180
DBUG_RETURN(0); // match
188
Checks whether a db matches wild_do_table and wild_ignore_table
189
rules (for replication)
192
db_ok_with_wild_table()
193
db name of the db to check.
194
Is tested with check_db_name() before calling this function.
197
Here is the reason for this function.
198
We advise users who want to exclude a database 'db1' safely to do it
199
with replicate_wild_ignore_table='db1.%' instead of binlog_ignore_db or
200
replicate_ignore_db because the two lasts only check for the selected db,
201
which won't work in that case:
203
UPDATE db1.t SET ... #this will be replicated and should not
204
whereas replicate_wild_ignore_table will work in all cases.
205
With replicate_wild_ignore_table, we only check tables. When
206
one does 'DROP DATABASE db1', tables are not involved and the
207
statement will be replicated, while users could expect it would not (as it
208
rougly means 'DROP db1.first_table, DROP db1.second_table...').
209
In other words, we want to interpret 'db1.%' as "everything touching db1".
210
That is why we want to match 'db1' against 'db1.%' wild table rules.
213
0 should not be logged/replicated
214
1 should be logged/replicated
218
Rpl_filter::db_ok_with_wild_table(const char *db)
220
DBUG_ENTER("Rpl_filter::db_ok_with_wild_table");
222
char hash_key[NAME_LEN+2];
225
end= strmov(hash_key, db);
227
len= end - hash_key ;
228
if (wild_do_table_inited && find_wild(&wild_do_table, hash_key, len))
230
DBUG_PRINT("return",("1"));
233
if (wild_ignore_table_inited && find_wild(&wild_ignore_table, hash_key, len))
235
DBUG_PRINT("return",("0"));
240
If no explicit rule found and there was a do list, do not replicate.
241
If there was no do list, go ahead
243
DBUG_PRINT("return",("db=%s,retval=%d", db, !wild_do_table_inited));
244
DBUG_RETURN(!wild_do_table_inited);
251
return table_rules_on;
256
Rpl_filter::add_do_table(const char* table_spec)
258
DBUG_ENTER("Rpl_filter::add_do_table");
259
if (!do_table_inited)
260
init_table_rule_hash(&do_table, &do_table_inited);
262
DBUG_RETURN(add_table_rule(&do_table, table_spec));
267
Rpl_filter::add_ignore_table(const char* table_spec)
269
DBUG_ENTER("Rpl_filter::add_ignore_table");
270
if (!ignore_table_inited)
271
init_table_rule_hash(&ignore_table, &ignore_table_inited);
273
DBUG_RETURN(add_table_rule(&ignore_table, table_spec));
278
Rpl_filter::add_wild_do_table(const char* table_spec)
280
DBUG_ENTER("Rpl_filter::add_wild_do_table");
281
if (!wild_do_table_inited)
282
init_table_rule_array(&wild_do_table, &wild_do_table_inited);
284
DBUG_RETURN(add_wild_table_rule(&wild_do_table, table_spec));
289
Rpl_filter::add_wild_ignore_table(const char* table_spec)
291
DBUG_ENTER("Rpl_filter::add_wild_ignore_table");
292
if (!wild_ignore_table_inited)
293
init_table_rule_array(&wild_ignore_table, &wild_ignore_table_inited);
295
DBUG_RETURN(add_wild_table_rule(&wild_ignore_table, table_spec));
300
Rpl_filter::add_db_rewrite(const char* from_db, const char* to_db)
302
i_string_pair *db_pair = new i_string_pair(from_db, to_db);
303
rewrite_db.push_back(db_pair);
308
Rpl_filter::add_table_rule(HASH* h, const char* table_spec)
310
const char* dot = strchr(table_spec, '.');
312
// len is always > 0 because we know the there exists a '.'
313
uint len = (uint)strlen(table_spec);
314
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
317
e->db= (char*)e + sizeof(TABLE_RULE_ENT);
318
e->tbl_name= e->db + (dot - table_spec) + 1;
320
memcpy(e->db, table_spec, len);
322
return my_hash_insert(h, (uchar*)e);
327
Add table expression with wildcards to dynamic array
331
Rpl_filter::add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
333
const char* dot = strchr(table_spec, '.');
335
uint len = (uint)strlen(table_spec);
336
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
339
e->db= (char*)e + sizeof(TABLE_RULE_ENT);
340
e->tbl_name= e->db + (dot - table_spec) + 1;
342
memcpy(e->db, table_spec, len);
343
insert_dynamic(a, (uchar*)&e);
349
Rpl_filter::add_do_db(const char* table_spec)
351
DBUG_ENTER("Rpl_filter::add_do_db");
352
i_string *db = new i_string(table_spec);
358
Rpl_filter::add_ignore_db(const char* table_spec)
360
DBUG_ENTER("Rpl_filter::add_ignore_db");
361
i_string *db = new i_string(table_spec);
362
ignore_db.push_back(db);
365
extern "C" uchar *get_table_key(const uchar *, size_t *, my_bool);
366
extern "C" void free_table_ent(void* a);
368
uchar *get_table_key(const uchar* a, size_t *len,
369
my_bool __attribute__((unused)))
371
TABLE_RULE_ENT *e= (TABLE_RULE_ENT *) a;
374
return (uchar*)e->db;
378
void free_table_ent(void* a)
380
TABLE_RULE_ENT *e= (TABLE_RULE_ENT *) a;
382
my_free((uchar*) e, MYF(0));
387
Rpl_filter::init_table_rule_hash(HASH* h, bool* h_inited)
389
hash_init(h, system_charset_info,TABLE_RULE_HASH_SIZE,0,0,
390
get_table_key, free_table_ent, 0);
396
Rpl_filter::init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited)
398
my_init_dynamic_array(a, sizeof(TABLE_RULE_ENT*), TABLE_RULE_ARR_SIZE,
399
TABLE_RULE_ARR_SIZE);
405
Rpl_filter::find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
408
const char* key_end= key + len;
410
for (i= 0; i < a->elements; i++)
413
get_dynamic(a, (uchar*)&e, i);
414
if (!my_wildcmp(system_charset_info, key, key_end,
416
(const char*)(e->db + e->key_len),
417
'\\',wild_one,wild_many))
426
Rpl_filter::free_string_array(DYNAMIC_ARRAY *a)
429
for (i= 0; i < a->elements; i++)
432
get_dynamic(a, (uchar*) &p, i);
433
my_free(p, MYF(MY_WME));
440
Builds a String from a HASH of TABLE_RULE_ENT. Cannot be used for any other
441
hash, as it assumes that the hash entries are TABLE_RULE_ENT.
444
table_rule_ent_hash_to_str()
445
s pointer to the String to fill
446
h pointer to the HASH to read
453
Rpl_filter::table_rule_ent_hash_to_str(String* s, HASH* h, bool inited)
458
for (uint i= 0; i < h->records; i++)
460
TABLE_RULE_ENT* e= (TABLE_RULE_ENT*) hash_element(h, i);
463
s->append(e->db,e->key_len);
470
Rpl_filter::table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a,
476
for (uint i= 0; i < a->elements; i++)
479
get_dynamic(a, (uchar*)&e, i);
482
s->append(e->db,e->key_len);
489
Rpl_filter::get_do_table(String* str)
491
table_rule_ent_hash_to_str(str, &do_table, do_table_inited);
496
Rpl_filter::get_ignore_table(String* str)
498
table_rule_ent_hash_to_str(str, &ignore_table, ignore_table_inited);
503
Rpl_filter::get_wild_do_table(String* str)
505
table_rule_ent_dynamic_array_to_str(str, &wild_do_table, wild_do_table_inited);
510
Rpl_filter::get_wild_ignore_table(String* str)
512
table_rule_ent_dynamic_array_to_str(str, &wild_ignore_table, wild_ignore_table_inited);
517
Rpl_filter::get_rewrite_db(const char* db, size_t *new_len)
519
if (rewrite_db.is_empty() || !db)
521
I_List_iterator<i_string_pair> it(rewrite_db);
526
if (!strcmp(tmp->key, db))
528
*new_len= strlen(tmp->val);
537
Rpl_filter::get_do_db()
544
Rpl_filter::get_ignore_db()