MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Luís Soares Date:June 5 2009 8:37am
Subject:Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:2874)
Bug#42941
View as plain text  
I Agree. Will do.

Thanks.

On Fri, 2009-05-29 at 19:33 +0100, Alfranio Correia wrote:
> Hi, we need to improve the idea of the hash.
> 
> There may be several TABLE_MAP_EVENTS before an event with
> the flag STMT_END_F and as such the hash needs to be reset
> erasing all the previous bookkeeping.
> 
> Cheers.
> 
> Luis Soares wrote:
> > #At file:///home/lsoares/Workspace/mysql-server/bugfix/b42941/5.1-bt/ based on
> revid:mats@stripped
> >
> >  2874 Luis Soares	2009-05-27
> >       BUG#42941: --database paramater to mysqlbinlog fails with RBR
> >       
> >       mysqlbinlog --database parameter was being ignored when processing
> >       row events. As such no event filtering would take place.
> >       
> >       This patch addresses this by deploying a call to shall_skip_database
> >       when table_map_events are handled (as these contain also the name of
> >       the database). All other rows events referencing the table id for the
> >       filtered map event, will also be skipped.
> >      @ client/mysqlbinlog.cc
> >         Added shall_skip_database call to the part of the code that handles 
> >         Table_map_log_events. It inspects the database name and decides whether
> >         to filter the event or not. Furthermore, if table map event is filtered
> >         next events referencing the table id in the table map event, will also
> >         be filtered.
> >      @ mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
> >         Test case that checks if row events are actually filtered out.
> >      @ sql/log_event.h
> >         Added a map for holding the currently ignored table map events.
> >         Table map events are inserted when they shall be skipped and removed
> >         once the last row event in the statement referencing this event is 
> >         processed.
> >
> >     added:
> >       mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result
> >       mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
> >     modified:
> >       client/mysqlbinlog.cc
> >       sql/log_event.h
> > === modified file 'client/mysqlbinlog.cc'
> > --- a/client/mysqlbinlog.cc	2009-05-08 17:24:15 +0000
> > +++ b/client/mysqlbinlog.cc	2009-05-27 15:37:01 +0000
> > @@ -681,6 +681,7 @@ Exit_status process_event(PRINT_EVENT_IN
> >  {
> >    char ll_buff[21];
> >    Log_event_type ev_type= ev->get_type_code();
> > +  my_bool destroy_evt= TRUE;
> >    DBUG_ENTER("process_event");
> >    print_event_info->short_form= short_form;
> >    Exit_status retval= OK_CONTINUE;
> > @@ -871,12 +872,57 @@ Exit_status process_event(PRINT_EVENT_IN
> >        break;
> >      }
> >      case TABLE_MAP_EVENT:
> > +    {
> > +      Table_map_log_event *map= ((Table_map_log_event *)ev);
> > +      if (shall_skip_database(map->get_db_name()))
> > +      {
> > +       
> print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map);
> > +        destroy_evt= FALSE;
> > +        goto end;
> > +      }
> > +    }
> >      case WRITE_ROWS_EVENT:
> >      case DELETE_ROWS_EVENT:
> >      case UPDATE_ROWS_EVENT:
> >      case PRE_GA_WRITE_ROWS_EVENT:
> >      case PRE_GA_DELETE_ROWS_EVENT:
> >      case PRE_GA_UPDATE_ROWS_EVENT:
> > +    {
> > +      if (ev_type != TABLE_MAP_EVENT)
> > +      {
> > +        Rows_log_event *e= (Rows_log_event*) ev;
> > +        Table_map_log_event *ignored= 
> > +         
> print_event_info->m_table_map_ignored.get_table(e->get_table_id());
> > +        if (ignored) /* map got filtered before, now filter rest of events */
> > +        {
> > +          /* 
> > +             one needs to take into account events that get filtered
> > +             but was last event in the statement. Cache still needs to
> > +             be written to file. (Especially needed on multi table updates
> > +             from different databases).
> > +           */
> > +          if (e->get_flags(Rows_log_event::STMT_END_F))
> > +          {
> > +            int error= 0;
> > +            error=
> (copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file)
> ||
> > +                   
> copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file));
> > +
> > +            /* clean up */
> > +           
> print_event_info->m_table_map_ignored.remove_table(e->get_table_id());
> > +
> > +            /* now is safe to destroy the original map event. */
> > +            if (remote_opt)
> > +              ignored->temp_buf= 0;
> > +            delete ignored;
> > +
> > +            if (error)
> > +              goto err;
> > +          }
> > +
> > +          /* filter event */
> > +          goto end;
> > +        }
> > +      }
> >        /*
> >          These events must be printed in base64 format, if printed.
> >          base64 format requires a FD event to be safe, so if no FD
> > @@ -900,6 +946,7 @@ Exit_status process_event(PRINT_EVENT_IN
> >          goto err;
> >        }
> >        /* FALL THROUGH */
> > +    }
> >      default:
> >        ev->print(result_file, print_event_info);
> >      }
> > @@ -915,7 +962,7 @@ end:
> >      Destroy the log_event object. If reading from a remote host,
> >      set the temp_buf to NULL so that memory isn't freed twice.
> >    */
> > -  if (ev)
> > +  if (ev && destroy_evt)
> >    {
> >      if (remote_opt)
> >        ev->temp_buf= 0;
> >
> > === added file
> 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result'
> > ---
> a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result	1970-01-01 00:00:00
> +0000
> > +++
> b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_db_filter.result	2009-05-27 15:37:01
> +0000
> > @@ -0,0 +1,36 @@
> > +RESET MASTER;
> > +CREATE TABLE t1 (id int);
> > +CREATE TABLE t2 (id int);
> > +CREATE TABLE t3 (txt TEXT);
> > +INSERT INTO t1 VALUES (1);
> > +INSERT INTO t1 VALUES (2);
> > +INSERT INTO t2 VALUES (1);
> > +INSERT INTO t2 VALUES (2);
> > +INSERT INTO t1 VALUES (3);
> > +LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3;
> > +INSERT INTO t1 VALUES (4);
> > +CREATE DATABASE b42941;
> > +use b42941;
> > +CREATE TABLE t1 (id int);
> > +CREATE TABLE t2 (id int);
> > +CREATE TABLE t3 (txt TEXT);
> > +INSERT INTO t1 VALUES (1);
> > +INSERT INTO t1 VALUES (2);
> > +INSERT INTO t2 VALUES (1);
> > +INSERT INTO t2 VALUES (2);
> > +INSERT INTO t1 VALUES (3);
> > +LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3;
> > +INSERT INTO t1 VALUES (4);
> > +INSERT INTO test.t1 VALUES (5);
> > +FLUSH LOGS;
> > +UPDATE test.t1 t11, b42941.t1 t12 SET t11.id=10, t12.id=100;
> > +FLUSH LOGS;
> > +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1');
> > +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2');
> > +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1');
> > +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2');
> > +SET @b42941_output.1= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.1');
> > +SET @b42941_output.2= LOAD_FILE('MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog.2');
> > +DROP DATABASE b42941;
> > +use test;
> > +DROP TABLE t1, t2, t3;
> >
> > === added file
> 'mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test'
> > --- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test	1970-01-01
> 00:00:00 +0000
> > +++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test	2009-05-27
> 15:37:01 +0000
> > @@ -0,0 +1,134 @@
> > +# BUG#42941: --database paramater to mysqlbinlog fails with RBR
> > +#
> > +# WHAT
> > +# ====
> > +#
> > +#  This test aims at checking whether a rows log event is printed or
> > +#  not when --database parameter is used to filter events from one
> > +#  given database.
> > +#
> > +# HOW
> > +# ===
> > +#
> > +#  The test is implemented as follows: 
> > +#
> > +#    i) Some operations are done in two different databases:
> > +#       'test' and 'b42941';
> > +#   ii) mysqlbinlog is used to dump the contents of the binlog file
> > +#       filtering only events from 'b42941'. The result of the dump is
> > +#       stored in a temporary file. (This is done with and without
> > +#       --verbose/hexdump flag);
> > +#  iii) The contents of the dump are loaded into a session variable;
> > +#   iv) The variable contents are searched for 'test' and 'b42941';
> > +#    v) Should 'test' be found, an ERROR is reported. Should 'b42941' be
> > +#       absent, an ERROR is reported.
> > +
> > +-- source include/have_log_bin.inc
> > +-- source include/have_binlog_format_row.inc
> > +
> > +RESET MASTER;
> > +-- let $MYSQLD_DATADIR= `select @@datadir`
> > +
> > +CREATE TABLE t1 (id int);
> > +CREATE TABLE t2 (id int);
> > +CREATE TABLE t3 (txt TEXT);
> > +INSERT INTO t1 VALUES (1);
> > +INSERT INTO t1 VALUES (2);
> > +INSERT INTO t2 VALUES (1);
> > +INSERT INTO t2 VALUES (2);
> > +INSERT INTO t1 VALUES (3);
> > +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> > +-- eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3
> > +INSERT INTO t1 VALUES (4);
> > +
> > +CREATE DATABASE b42941;
> > +use b42941;
> > +CREATE TABLE t1 (id int);
> > +CREATE TABLE t2 (id int);
> > +CREATE TABLE t3 (txt TEXT);
> > +INSERT INTO t1 VALUES (1);
> > +INSERT INTO t1 VALUES (2);
> > +INSERT INTO t2 VALUES (1);
> > +INSERT INTO t2 VALUES (2);
> > +INSERT INTO t1 VALUES (3);
> > +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> > +-- eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/std_data/words.dat' INTO TABLE t3
> > +INSERT INTO t1 VALUES (4);
> > +
> > +INSERT INTO test.t1 VALUES (5);
> > +
> > +FLUSH LOGS;
> > +
> > +UPDATE test.t1 t11, b42941.t1 t12 SET t11.id=10, t12.id=100;
> > +
> > +FLUSH LOGS;
> > +
> > +-- let $log_file1= $MYSQLD_DATADIR/master-bin.000001
> > +-- let $log_file2= $MYSQLD_DATADIR/master-bin.000002
> > +-- let $outfile= $MYSQLTEST_VARDIR/tmp/b42941-mysqlbinlog
> > +-- let $cmd= $MYSQL_BINLOG
> > +
> > +let $i= 3;
> > +while($i)
> > +{
> > +  -- let $flags=--database=b42941
> > +
> > +  # construct CLI for mysqlbinlog
> > +  if(`SELECT $i=3`)
> > +  {
> > +    -- let $flags= $flags --verbose --hexdump
> > +  }
> > +
> > +  if(`SELECT $i=2`)
> > +  {
> > +    -- let $flags= $flags --verbose
> > +  }
> > +
> > +  if(`SELECT $i=0`)
> > +  {
> > +    # do nothing
> > +  }
> > +
> > +  # execute mysqlbinlog on the two available master binlog files
> > +  -- exec $cmd $flags $log_file1 > $outfile.1
> > +  -- exec $cmd $flags $log_file2 > $outfile.2
> > +
> > +  # load outputs into a variable
> > +  -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> > +  -- eval SET @b42941_output.1= LOAD_FILE('$outfile.1')
> > +
> > +  -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> > +  -- eval SET @b42941_output.2= LOAD_FILE('$outfile.2')
> > +
> > +  # remove unecessary files
> > +  -- remove_file $outfile.1
> > +  -- remove_file $outfile.2
> > +
> > +  # assertion: events for database test are filtered
> > +  if (`SELECT INSTR(@b42941_output.1, 'test')`)
> > +  {
> > +    -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output
> ($flags $outfile.1).
> > +  }
> > +
> > +  if (`SELECT INSTR(@b42941_output.2, 'test')`)
> > +  {
> > +    -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output
> ($flags $outfile.2).
> > +  }
> > +
> > +  # assertion: events for database b42941 are not filtered
> > +  if (!`SELECT INSTR(@b42941_output.1, 'b42941')`)
> > +  {
> > +    -- echo **** ERROR **** Database name 'b42941' NOT FOUND in mysqlbinlog
> output ($flags $outfile.1).
> > +  }
> > +
> > +  if (!`SELECT INSTR(@b42941_output.2, 'b42941')`)
> > +  {
> > +    -- echo **** ERROR **** Database name 'b42941' NOT FOUND in mysqlbinlog
> output ($flags $outfile.2).
> > +  }
> > +
> > +  dec $i;
> > +}
> > +
> > +DROP DATABASE b42941;
> > +use test;
> > +DROP TABLE t1, t2, t3;
> >
> > === modified file 'sql/log_event.h'
> > --- a/sql/log_event.h	2009-04-08 23:42:51 +0000
> > +++ b/sql/log_event.h	2009-05-27 15:37:01 +0000
> > @@ -676,6 +676,7 @@ typedef struct st_print_event_info
> >  #ifdef MYSQL_CLIENT
> >    uint verbose;
> >    table_mapping m_table_map;
> > +  table_mapping m_table_map_ignored;
> >  #endif
> >  
> >    /*
> >
> >   
> > ------------------------------------------------------------------------
> >
> >
> >   
> 
-- 
Luís

Thread
bzr commit into mysql-5.1-bugteam branch (luis.soares:2874) Bug#42941Luis Soares27 May
  • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:2874)Bug#42941Alfranio Correia29 May
    • Re: bzr commit into mysql-5.1-bugteam branch (luis.soares:2874)Bug#42941Luís Soares5 Jun