~maria-captains/maria/5.5-davi

« back to all changes in this revision

Viewing changes to sql/rpl_filter.cc

  • Committer: Davi Arnaut
  • Date: 2012-03-19 22:00:23 UTC
  • Revision ID: davi@twitter.com-20120319220023-77a84i1t1n18pzt7
Make Replication filter settings dynamic.

Make the slave options --replicate-* dynamic variables so that these
options can be changed dynamically while the server is running,
which enables users to modify replication filtering rules without
having to stop and restart the server.

This is accomplished by just requiring that the slave threads are
stopped when these options are set dynamically. Since filtering
rules are only used by the SQL slave thread, setting them while the
thread is not running avoids the need for locking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
    free_string_array(&wild_do_table);
43
43
  if (wild_ignore_table_inited)
44
44
    free_string_array(&wild_ignore_table);
45
 
  free_list(&do_db);
46
 
  free_list(&ignore_db);
 
45
  free_string_list(&do_db);
 
46
  free_string_list(&ignore_db);
47
47
  free_list(&rewrite_db);
48
48
}
49
49
 
263
263
}
264
264
 
265
265
 
 
266
/**
 
267
  Parse and add the given comma-separated sequence of filter rules.
 
268
 
 
269
  @param  spec  Comma-separated sequence of filter rules.
 
270
  @param  add   Callback member function to add a filter rule.
 
271
 
 
272
  @return true if error, false otherwise.
 
273
*/
 
274
 
 
275
int
 
276
Rpl_filter::parse_filter_rule(const char* spec, Add_filter add)
 
277
{
 
278
  int status= 0;
 
279
  char *arg, *ptr, *pstr;
 
280
 
 
281
  if (! (ptr= my_strdup(spec, MYF(MY_WME))))
 
282
    return true;
 
283
 
 
284
  pstr= ptr;
 
285
 
 
286
  while (pstr)
 
287
  {
 
288
    arg= pstr;
 
289
 
 
290
    /* Parse token string. */
 
291
    pstr= strpbrk(arg, ",");
 
292
 
 
293
    /* NUL terminate the token string. */
 
294
    if (pstr)
 
295
      *pstr++= '\0';
 
296
 
 
297
    /* Skip an empty token string. */
 
298
    if (arg[0] == '\0')
 
299
      continue;
 
300
 
 
301
    /* Skip leading spaces.  */
 
302
    while (my_isspace(system_charset_info, *arg))
 
303
      arg++;
 
304
 
 
305
    status= (this->*add)(arg);
 
306
 
 
307
    if (status)
 
308
      break;
 
309
  }
 
310
 
 
311
  my_free(ptr);
 
312
 
 
313
  return status;
 
314
}
 
315
 
 
316
 
266
317
int 
267
318
Rpl_filter::add_do_table(const char* table_spec) 
268
319
{
285
336
}
286
337
 
287
338
 
 
339
int
 
340
Rpl_filter::set_do_table(const char* table_spec)
 
341
{
 
342
  int status;
 
343
 
 
344
  if (do_table_inited)
 
345
    my_hash_reset(&do_table);
 
346
 
 
347
  status= parse_filter_rule(table_spec, &Rpl_filter::add_do_table);
 
348
 
 
349
  if (!do_table.records)
 
350
  {
 
351
    my_hash_free(&do_table);
 
352
    do_table_inited= 0;
 
353
  }
 
354
 
 
355
  return status;
 
356
}
 
357
 
 
358
 
 
359
int
 
360
Rpl_filter::set_ignore_table(const char* table_spec)
 
361
{
 
362
  int status;
 
363
 
 
364
  if (ignore_table_inited)
 
365
    my_hash_reset(&ignore_table);
 
366
 
 
367
  status= parse_filter_rule(table_spec, &Rpl_filter::add_ignore_table);
 
368
 
 
369
  if (!ignore_table.records)
 
370
  {
 
371
    my_hash_free(&ignore_table);
 
372
    ignore_table_inited= 0;
 
373
  }
 
374
 
 
375
  return status;
 
376
}
 
377
 
 
378
 
288
379
int 
289
380
Rpl_filter::add_wild_do_table(const char* table_spec)
290
381
{
307
398
}
308
399
 
309
400
 
 
401
int
 
402
Rpl_filter::set_wild_do_table(const char* table_spec)
 
403
{
 
404
  int status;
 
405
 
 
406
  if (wild_do_table_inited)
 
407
    free_string_array(&wild_do_table);
 
408
 
 
409
  status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_do_table);
 
410
 
 
411
  if (!wild_do_table.elements)
 
412
  {
 
413
    delete_dynamic(&wild_do_table);
 
414
    wild_do_table_inited= 0;
 
415
  }
 
416
 
 
417
  return status;
 
418
}
 
419
 
 
420
 
 
421
int
 
422
Rpl_filter::set_wild_ignore_table(const char* table_spec)
 
423
{
 
424
  int status;
 
425
 
 
426
  if (wild_ignore_table_inited)
 
427
    free_string_array(&wild_ignore_table);
 
428
 
 
429
  status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_ignore_table);
 
430
 
 
431
  if (!wild_ignore_table.elements)
 
432
  {
 
433
    delete_dynamic(&wild_ignore_table);
 
434
    wild_ignore_table_inited= 0;
 
435
  }
 
436
 
 
437
  return status;
 
438
}
 
439
 
 
440
 
310
441
void
311
442
Rpl_filter::add_db_rewrite(const char* from_db, const char* to_db)
312
443
{
355
486
}
356
487
 
357
488
 
358
 
void
 
489
int
 
490
Rpl_filter::add_string_list(I_List<i_string> *list, const char* spec)
 
491
{
 
492
  char *str;
 
493
  i_string *node;
 
494
 
 
495
  if (! (str= my_strdup(spec, MYF(MY_WME))))
 
496
    return true;
 
497
 
 
498
  if (! (node= new i_string(str)))
 
499
  {
 
500
    my_free(str);
 
501
    return true;
 
502
  }
 
503
 
 
504
  list->push_back(node);
 
505
 
 
506
  return false;
 
507
}
 
508
 
 
509
 
 
510
int
359
511
Rpl_filter::add_do_db(const char* table_spec)
360
512
{
361
513
  DBUG_ENTER("Rpl_filter::add_do_db");
362
 
  i_string *db = new i_string(table_spec);
363
 
  do_db.push_back(db);
364
 
  DBUG_VOID_RETURN;
 
514
  DBUG_RETURN(add_string_list(&do_db, table_spec));
365
515
}
366
516
 
367
517
 
368
 
void
 
518
int
369
519
Rpl_filter::add_ignore_db(const char* table_spec)
370
520
{
371
521
  DBUG_ENTER("Rpl_filter::add_ignore_db");
372
 
  i_string *db = new i_string(table_spec);
373
 
  ignore_db.push_back(db);
374
 
  DBUG_VOID_RETURN;
375
 
}
 
522
  DBUG_RETURN(add_string_list(&ignore_db, table_spec));
 
523
}
 
524
 
 
525
 
 
526
int
 
527
Rpl_filter::set_do_db(const char* db_spec)
 
528
{
 
529
  free_string_list(&do_db);
 
530
  return parse_filter_rule(db_spec, &Rpl_filter::add_do_db);
 
531
}
 
532
 
 
533
 
 
534
int
 
535
Rpl_filter::set_ignore_db(const char* db_spec)
 
536
{
 
537
  free_string_list(&ignore_db);
 
538
  return parse_filter_rule(db_spec, &Rpl_filter::add_ignore_db);
 
539
}
 
540
 
376
541
 
377
542
extern "C" uchar *get_table_key(const uchar *, size_t *, my_bool);
378
543
extern "C" void free_table_ent(void* a);
448
613
}
449
614
 
450
615
 
 
616
void
 
617
Rpl_filter::free_string_list(I_List<i_string> *l)
 
618
{
 
619
  void *ptr;
 
620
  i_string *tmp;
 
621
 
 
622
  while ((tmp= l->get()))
 
623
  {
 
624
    ptr= (void *) tmp->ptr;
 
625
    my_free(ptr);
 
626
    delete tmp;
 
627
  }
 
628
 
 
629
  l->empty();
 
630
}
 
631
 
 
632
 
451
633
/*
452
634
  Builds a String from a HASH of TABLE_RULE_ENT. Cannot be used for any other 
453
635
  hash, as it assumes that the hash entries are TABLE_RULE_ENT.
564
746
{
565
747
  return &ignore_db;
566
748
}
 
749
 
 
750
 
 
751
void
 
752
Rpl_filter::db_rule_ent_list_to_str(String* str, I_List<i_string>* list)
 
753
{
 
754
  I_List_iterator<i_string> it(*list);
 
755
  i_string* s;
 
756
 
 
757
  str->length(0);
 
758
 
 
759
  while ((s= it++))
 
760
  {
 
761
    str->append(s->ptr);
 
762
    str->append(',');
 
763
  }
 
764
 
 
765
  // Remove last ','
 
766
  if (!str->is_empty())
 
767
    str->chop();
 
768
}
 
769
 
 
770
 
 
771
void
 
772
Rpl_filter::get_do_db(String* str)
 
773
{
 
774
  db_rule_ent_list_to_str(str, get_do_db());
 
775
}
 
776
 
 
777
 
 
778
void
 
779
Rpl_filter::get_ignore_db(String* str)
 
780
{
 
781
  db_rule_ent_list_to_str(str, get_ignore_db());
 
782
}