← Back to team overview

maria-developers team mailing list archive

Re: ad6e7b87107: introduce cache flipping

 

Sergei,

On Sat, 13 Nov 2021 at 22:44, Sergei Golubchik <serg@xxxxxxxxxxx> wrote:

> Hi, Nikita!
>
> Interesting trick.
>
That was you who proposed it! :D

>
> On Nov 13, Nikita Malyavin wrote:
> > revision-id: ad6e7b87107 (mariadb-10.5.2-477-gad6e7b87107)
> > parent(s): 85fbd867b4c
> > author: Nikita Malyavin
> > committer: Nikita Malyavin
> > timestamp: 2021-01-27 14:17:39 +1000
> > message:
> >
> > introduce cache flipping
>
> Could you add few lines from the Cache_flip_event_log comment here too
> please?
>
> Right, thanks for pointing out.


> > diff --git a/sql/log.h b/sql/log.h
> > index 74c409e1ac7..1e422ae4524 100644
> > --- a/sql/log.h
> > +++ b/sql/log.h
> > @@ -424,10 +424,9 @@ class Event_log: public MYSQL_LOG
> >
> >    bool open(
> >            const char *log_name,
> > -          enum_log_type log_type,
> >            const char *new_name, ulong next_file_number,
> >            enum cache_type io_cache_type_arg);
> > -  IO_CACHE *get_log_file() { return &log_file; }
> > +  virtual IO_CACHE *get_log_file() { return &log_file; }
> >
> >    int write_description_event(enum_binlog_checksum_alg checksum_alg,
> >                                bool encrypt, bool dont_set_created);
> > @@ -435,6 +434,73 @@ class Event_log: public MYSQL_LOG
> >    bool write_event(Log_event *ev, binlog_cache_data *data, IO_CACHE
> *file);
> >  };
> >
> > +/**
> > +  A single-reader, multiple-writer non-blocking layer for Event_log.
> > +  Provides IO_CACHE for writing and IO_CACHE for reading.\
> > +
> > +  Writers use an overrided get_log_file version for their writes, while
> readers
> > +  should use flip() to initiate reading.
> > +  flip() swaps pointers to allow non-blocking reads.
> > +
> > +  Writers can block other writers and a reader with a mutex, but a
> reader only
> > +  swaps two pointers under a lock, so it won't block writers.
> > +
> > +  TODO should be unnecessary after MDEV-24676 is done
> > + */
> > +class Cache_flip_event_log: public Event_log {
> > +  IO_CACHE alt_buf;
> > +  IO_CACHE *current, *alt;
> > +public:
> > +
> > +  Cache_flip_event_log() : Event_log(), alt_buf{},
> > +                           current(&log_file), alt(&alt_buf) {}
> > +  bool open(enum cache_type io_cache_type_arg)
> > +  {
> > +    log_file.dir= mysql_tmpdir;
> > +    alt_buf.dir= log_file.dir;
> > +    bool res= Event_log::open(NULL, NULL, 0, io_cache_type_arg);
> > +    if (res)
> > +      return res;
> > +
> > +    name= my_strdup(key_memory_MYSQL_LOG_name, "online-alter-binlog",
> > +                    MYF(MY_WME));
> > +    if (!name)
> > +      return false;
> > +
> > +    res= init_io_cache(&alt_buf, -1, LOG_BIN_IO_SIZE,
> io_cache_type_arg, 0, 0,
> > +                       MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0;
> > +    return res;
> > +  }
> > +
> > +  /**
> > +    Swaps current and alt_log. Can be called only from the reader
> thread.
> > +    @return a new IO_CACHE pointer to read from.
> > +   */
> > +  IO_CACHE *flip()
> > +  {
> > +    IO_CACHE *tmp= current;
> > +    reinit_io_cache(alt, WRITE_CACHE, 0, 0, 0);
> > +    mysql_mutex_lock(get_log_lock());
> > +    reinit_io_cache(current, READ_CACHE, 0, 0, 0);
> > +    current= alt;
> > +    mysql_mutex_unlock(get_log_lock());
> > +    alt= tmp;
> > +
> > +    return alt;
> > +  }
> > +
> > +  IO_CACHE *get_log_file() override
> > +  {
> > +    return current;
>
> may be mysql_mutex_assert_owner(get_log_lock()) ?
>
> Good point! Seems so.

> > +  }
> > +
> > +  void cleanup()
> > +  {
> > +    end_io_cache(&alt_buf);
> > +    Event_log::cleanup();
> > +  }
> > +};
> > +
>
> Regards,
> Sergei
> VP of MariaDB Server Engineering
> and security@xxxxxxxxxxx
>


-- 
Yours truly,
Nikita Malyavin

References