This is a preparatory commit for pre-computing checksums outside of
holding LOCK_log, no functional changes.

Which checksum algorithm is used (if any) when writing an event does not
belong in the event, it is a property of the log being written to.

Instead decide the checksum algorithm when constructing the
Log_event_writer object, and store it there.

Introduce a client-only Log_event::read_checksum_alg to be able to
print the checksum read, and a
Format_description_log_event::source_checksum_alg which is the
checksum algorithm (if any) to use when reading events from a log.

Signed-off-by: Kristian Nielsen <kniel...@knielsen-hq.org>
---
 .../r/binlog_mysqlbinlog_raw_flush.result     |   1 +
 .../t/binlog_mysqlbinlog_raw_flush.test       |   2 +
 sql/log.cc                                    | 104 +++++++++-------
 sql/log.h                                     |  12 +-
 sql/log_event.cc                              |  27 +++--
 sql/log_event.h                               |  52 +++++---
 sql/log_event_client.cc                       |  22 ++--
 sql/log_event_server.cc                       | 114 ++++--------------
 sql/slave.cc                                  |  60 ++++-----
 sql/sql_repl.cc                               |   2 +-
 sql/wsrep_binlog.cc                           |   6 +-
 sql/wsrep_mysqld.cc                           |  12 +-
 12 files changed, 202 insertions(+), 212 deletions(-)

diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result 
b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
index 294e96e5997..d697788047f 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_raw_flush.result
@@ -1,3 +1,4 @@
+RESET MASTER;
 #
 # MDEV-30698 Cover missing test cases for mariadb-binlog options
 #            --raw [and] --flashback
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test 
b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
index 252a8577b6c..7d0a96fc087 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_raw_flush.test
@@ -21,6 +21,8 @@
 --source include/linux.inc
 --source include/have_log_bin.inc
 
+RESET MASTER;
+
 --echo #
 --echo # MDEV-30698 Cover missing test cases for mariadb-binlog options
 --echo #            --raw [and] --flashback
diff --git a/sql/log.cc b/sql/log.cc
index ab7c9e8ba0d..bcb89e79dd0 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -3886,32 +3886,34 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
         In 4.x we put Start event only in the first binlog. But from 5.0 we
         want a Start event even if this is not the very first binlog.
       */
-      Format_description_log_event s(BINLOG_VERSION);
-      /*
-        don't set LOG_EVENT_BINLOG_IN_USE_F for SEQ_READ_APPEND io_cache
-        as we won't be able to reset it later
-      */
-      if (io_cache_type == WRITE_CACHE)
-        s.flags |= LOG_EVENT_BINLOG_IN_USE_F;
-
+      enum enum_binlog_checksum_alg checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
       if (is_relay_log)
       {
         if (relay_log_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
           relay_log_checksum_alg=
             opt_slave_sql_verify_checksum ? (enum_binlog_checksum_alg) 
binlog_checksum_options
                                           : BINLOG_CHECKSUM_ALG_OFF;
-        s.checksum_alg= relay_log_checksum_alg;
-        s.set_relay_log_event();
+        checksum_alg= relay_log_checksum_alg;
       }
       else
-        s.checksum_alg= (enum_binlog_checksum_alg)binlog_checksum_options;
+        checksum_alg= (enum_binlog_checksum_alg)binlog_checksum_options;
+      DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+
+      Format_description_log_event s(BINLOG_VERSION, NULL, checksum_alg);
+      if (is_relay_log)
+        s.set_relay_log_event();
+      /*
+        don't set LOG_EVENT_BINLOG_IN_USE_F for SEQ_READ_APPEND io_cache
+        as we won't be able to reset it later
+      */
+      if (io_cache_type == WRITE_CACHE)
+        s.flags |= LOG_EVENT_BINLOG_IN_USE_F;
 
       crypto.scheme = 0;
-      DBUG_ASSERT(s.checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
       if (!s.is_valid())
         goto err;
       s.dont_set_created= null_created_arg;
-      if (write_event(&s))
+      if (write_event(&s, checksum_alg))
         goto err;
       bytes_written+= s.data_written;
 
@@ -3930,8 +3932,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
             goto err;
 
           Start_encryption_log_event sele(1, key_version, crypto.nonce);
-          sele.checksum_alg= s.checksum_alg;
-          if (write_event(&sele))
+          if (write_event(&sele, checksum_alg))
             goto err;
 
           // Start_encryption_log_event is written, enable the encryption
@@ -4057,7 +4058,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
       /* Don't set log_pos in event header */
       description_event_for_queue->set_artificial_event();
 
-      if (write_event(description_event_for_queue))
+      if (write_event(description_event_for_queue,
+                      description_event_for_queue->used_checksum_alg))
         goto err;
       bytes_written+= description_event_for_queue->data_written;
     }
@@ -5500,17 +5502,19 @@ int MYSQL_BIN_LOG::new_file_impl()
     */
     Rotate_log_event r(new_name + dirname_length(new_name), 0, 
LOG_EVENT_OFFSET,
                        is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
+    enum enum_binlog_checksum_alg checksum_alg = BINLOG_CHECKSUM_ALG_UNDEF;
     /*
       The current relay-log's closing Rotate event must have checksum
       value computed with an algorithm of the last relay-logged FD event.
     */
     if (is_relay_log)
-      r.checksum_alg= relay_log_checksum_alg;
-    DBUG_ASSERT(!is_relay_log ||
-                relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+      checksum_alg= relay_log_checksum_alg;
+    else
+      checksum_alg= (enum_binlog_checksum_alg)binlog_checksum_options;
+    DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
     if ((DBUG_IF("fault_injection_new_file_rotate_event") &&
                          (error= close_on_error= TRUE)) ||
-        (error= write_event(&r)))
+        (error= write_event(&r, checksum_alg)))
     {
       DBUG_EXECUTE_IF("fault_injection_new_file_rotate_event", errno= 2;);
       close_on_error= TRUE;
@@ -5627,10 +5631,22 @@ int MYSQL_BIN_LOG::new_file_impl()
   DBUG_RETURN(error);
 }
 
-bool MYSQL_BIN_LOG::write_event(Log_event *ev, binlog_cache_data *cache_data,
+bool MYSQL_BIN_LOG::write_event(Log_event *ev, binlog_cache_data *data,
                                 IO_CACHE *file)
 {
-  Log_event_writer writer(file, 0, &crypto);
+  return write_event(ev, ev->select_checksum_alg(), data, file);
+}
+
+bool MYSQL_BIN_LOG::write_event(Log_event *ev)
+{
+  return write_event(ev, ev->select_checksum_alg(), 0, &log_file);
+}
+
+bool MYSQL_BIN_LOG::write_event(Log_event *ev,
+                                enum enum_binlog_checksum_alg checksum_alg,
+                                binlog_cache_data *cache_data, IO_CACHE *file)
+{
+  Log_event_writer writer(file, 0, checksum_alg, &crypto);
   if (crypto.scheme && file == &log_file)
   {
     writer.ctx= alloca(crypto.ctx_size);
@@ -5641,17 +5657,19 @@ bool MYSQL_BIN_LOG::write_event(Log_event *ev, 
binlog_cache_data *cache_data,
   return writer.write(ev);
 }
 
-bool MYSQL_BIN_LOG::append(Log_event *ev)
+bool MYSQL_BIN_LOG::append(Log_event *ev,
+                           enum enum_binlog_checksum_alg checksum_alg)
 {
   bool res;
   mysql_mutex_lock(&LOCK_log);
-  res= append_no_lock(ev);
+  res= append_no_lock(ev, checksum_alg);
   mysql_mutex_unlock(&LOCK_log);
   return res;
 }
 
 
-bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev)
+bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev,
+                                   enum enum_binlog_checksum_alg checksum_alg)
 {
   bool error = 0;
   DBUG_ENTER("MYSQL_BIN_LOG::append");
@@ -5659,7 +5677,7 @@ bool MYSQL_BIN_LOG::append_no_lock(Log_event* ev)
   mysql_mutex_assert_owner(&LOCK_log);
   DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
 
-  if (write_event(ev))
+  if (write_event(ev, checksum_alg))
   {
     error=1;
     goto err;
@@ -6051,7 +6069,8 @@ THD::binlog_start_trans_and_stmt()
       uchar *buf= 0;
       size_t len= 0;
       IO_CACHE tmp_io_cache;
-      Log_event_writer writer(&tmp_io_cache, 0);
+        // Replicated events in writeset doesn't have checksum
+      Log_event_writer writer(&tmp_io_cache, 0, BINLOG_CHECKSUM_ALG_OFF, NULL);
       if(!open_cached_file(&tmp_io_cache, mysql_tmpdir, TEMP_PREFIX,
                           128, MYF(MY_WME)))
       {
@@ -6066,8 +6085,6 @@ THD::binlog_start_trans_and_stmt()
         }
         Gtid_log_event gtid_event(this, seqno, domain_id, true,
                                   LOG_EVENT_SUPPRESS_USE_F, true, 0);
-        // Replicated events in writeset doesn't have checksum
-        gtid_event.checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
         gtid_event.server_id= server_id;
         writer.write(&gtid_event);
         wsrep_write_cache_buf(&tmp_io_cache, &buf, &len);
@@ -6270,7 +6287,7 @@ bool THD::binlog_write_table_map(TABLE *table, bool 
with_annotate)
   binlog_cache_data *cache_data= (cache_mngr->
                                   get_binlog_cache_data(is_transactional));
   IO_CACHE *file= &cache_data->cache_log;
-  Log_event_writer writer(file, cache_data);
+  Log_event_writer writer(file, cache_data, the_event.select_checksum_alg(), 
NULL);
 
   if (with_annotate)
     if (binlog_write_annotated_row(&writer))
@@ -6424,7 +6441,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
 
   if (Rows_log_event* pending= cache_data->pending())
   {
-    Log_event_writer writer(&cache_data->cache_log, cache_data);
+    Log_event_writer writer(&cache_data->cache_log, cache_data,
+                            pending->select_checksum_alg(), NULL);
 
     /*
       Write pending event to the cache.
@@ -7472,11 +7490,13 @@ class CacheWriter: public Log_event_writer
 public:
   size_t remains;
 
-  CacheWriter(THD *thd_arg, IO_CACHE *file_arg, bool do_checksum,
+  CacheWriter(THD *thd_arg, IO_CACHE *file_arg,
+              enum enum_binlog_checksum_alg checksum_alg,
               Binlog_crypt_data *cr)
-    : Log_event_writer(file_arg, 0, cr), remains(0), thd(thd_arg),
+    : Log_event_writer(file_arg, 0, checksum_alg, cr), remains(0), 
thd(thd_arg),
       first(true)
-  { checksum_len= do_checksum ? BINLOG_CHECKSUM_LEN : 0; }
+  {
+  }
 
   ~CacheWriter()
   { status_var_add(thd->status_var.binlog_bytes_written, bytes_written); }
@@ -7527,7 +7547,9 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
   size_t val;
   size_t end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 
2 t
   uchar header[LOG_EVENT_HEADER_LEN];
-  CacheWriter writer(thd, &log_file, binlog_checksum_options, &crypto);
+  CacheWriter writer(thd, &log_file,
+                     (enum_binlog_checksum_alg)binlog_checksum_options,
+                     &crypto);
 
   if (crypto.scheme)
   {
@@ -9070,11 +9092,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
     {
       Stop_log_event s;
       // the checksumming rule for relay-log case is similar to Rotate
-        s.checksum_alg= is_relay_log ? relay_log_checksum_alg
-                                     : 
(enum_binlog_checksum_alg)binlog_checksum_options;
-      DBUG_ASSERT(!is_relay_log ||
-                  relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
-      write_event(&s);
+      enum enum_binlog_checksum_alg checksum_alg= is_relay_log ?
+        relay_log_checksum_alg :
+        (enum_binlog_checksum_alg)binlog_checksum_options;
+      DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
+      write_event(&s, checksum_alg);
       bytes_written+= s.data_written;
       flush_io_cache(&log_file);
       update_binlog_end_pos();
@@ -11242,7 +11264,7 @@ bool 
Recovery_context::decide_or_assess(xid_recovery_member *member, int round,
           if (truncate_gtid.seq_no == 0 /* was reset or never set */ ||
               (truncate_set_in_1st && round == 2 /* reevaluted at round turn 
*/))
           {
-            if (set_truncate_coord(linfo, round, fdle->checksum_alg))
+            if (set_truncate_coord(linfo, round, fdle->used_checksum_alg))
               return true;
           }
           else
diff --git a/sql/log.h b/sql/log.h
index c20f0fe5a57..f02b20c12bf 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -829,12 +829,18 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
   void stop_union_events(THD *thd);
   bool is_query_in_union(THD *thd, query_id_t query_id_param);
 
+  bool write_event(Log_event *ev, enum enum_binlog_checksum_alg checksum_alg,
+                   binlog_cache_data *data, IO_CACHE *file);
   bool write_event(Log_event *ev, binlog_cache_data *data, IO_CACHE *file);
-  bool write_event(Log_event *ev) { return write_event(ev, 0, &log_file); }
+  bool write_event(Log_event *ev, enum enum_binlog_checksum_alg checksum_alg)
+  {
+    return write_event(ev, checksum_alg, 0, &log_file);
+  }
+  bool write_event(Log_event *ev);
 
   bool write_event_buffer(uchar* buf,uint len);
-  bool append(Log_event* ev);
-  bool append_no_lock(Log_event* ev);
+  bool append(Log_event* ev, enum enum_binlog_checksum_alg checksum_alg);
+  bool append_no_lock(Log_event* ev, enum enum_binlog_checksum_alg 
checksum_alg);
 
   void mark_xids_active(ulong cookie, uint xid_count);
   void mark_xid_done(ulong cookie, bool write_checkpoint);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5e255646528..7825e25086f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -718,8 +718,7 @@ const char* Log_event::get_type_str()
 
 Log_event::Log_event(const uchar *buf,
                      const Format_description_log_event* description_event)
-  :temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE),
-    checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
+  :temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE)
 {
 #ifndef MYSQL_CLIENT
   thd= 0;
@@ -1017,7 +1016,8 @@ Log_event* Log_event::read_log_event(const uchar *buf, 
uint event_len,
   uint event_type= buf[EVENT_TYPE_OFFSET];
   // all following START events in the current file are without checksum
   if (event_type == START_EVENT_V3)
-    (const_cast< Format_description_log_event *>(fdle))->checksum_alg= 
BINLOG_CHECKSUM_ALG_OFF;
+    (const_cast< Format_description_log_event *>(fdle))->used_checksum_alg=
+      BINLOG_CHECKSUM_ALG_OFF;
   /*
     CRC verification by SQL and Show-Binlog-Events master side.
     The caller has to provide @fdle->checksum_alg to
@@ -1038,7 +1038,7 @@ Log_event* Log_event::read_log_event(const uchar *buf, 
uint event_len,
     Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
   */
   alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
-    fdle->checksum_alg : get_checksum_alg(buf, event_len);
+    fdle->used_checksum_alg : get_checksum_alg(buf, event_len);
   // Emulate the corruption during reading an event
   DBUG_EXECUTE_IF("corrupt_read_log_event_char",
     if (event_type != FORMAT_DESCRIPTION_EVENT)
@@ -1258,11 +1258,10 @@ Log_event* Log_event::read_log_event(const uchar *buf, 
uint event_len,
 
   if (ev)
   {
-    ev->checksum_alg= alg;
 #ifdef MYSQL_CLIENT
-    if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
-        ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
-      ev->crc= uint4korr(buf + (event_len));
+    ev->read_checksum_alg= alg;
+    if (alg != BINLOG_CHECKSUM_ALG_OFF && alg != BINLOG_CHECKSUM_ALG_UNDEF)
+      ev->read_checksum_value= uint4korr(buf + (event_len));
 #endif
   }
 
@@ -2039,8 +2038,10 @@ Start_log_event_v3::Start_log_event_v3(const uchar *buf, 
uint event_len,
 */
 
 Format_description_log_event::
-Format_description_log_event(uint8 binlog_ver, const char* server_ver)
-  :Start_log_event_v3(), event_type_permutation(0)
+Format_description_log_event(uint8 binlog_ver, const char* server_ver,
+                             enum enum_binlog_checksum_alg checksum_alg)
+  :Start_log_event_v3(), event_type_permutation(0),
+   used_checksum_alg(checksum_alg)
 {
   binlog_version= binlog_ver;
   switch (binlog_ver) {
@@ -2205,7 +2206,6 @@ Format_description_log_event(uint8 binlog_ver, const 
char* server_ver)
   }
   calc_server_version_split();
   deduct_options_written_to_bin_log();
-  checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
   reset_crypto();
 }
 
@@ -2236,6 +2236,7 @@ Format_description_log_event(const uchar *buf, uint 
event_len,
    common_header_len(0), post_header_len(NULL), event_type_permutation(0)
 {
   
DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
+  used_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
   if (!Start_log_event_v3::is_valid())
     DBUG_VOID_RETURN; /* sanity check */
   buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
@@ -2257,11 +2258,11 @@ Format_description_log_event(const uchar *buf, uint 
event_len,
   {
     /* the last bytes are the checksum alg desc and value (or value's room) */
     number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
-    checksum_alg= 
(enum_binlog_checksum_alg)post_header_len[number_of_event_types];
+    used_checksum_alg= 
(enum_binlog_checksum_alg)post_header_len[number_of_event_types];
   }
   else
   {
-    checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
+    used_checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
   }
   deduct_options_written_to_bin_log();
   reset_crypto();
diff --git a/sql/log_event.h b/sql/log_event.h
index acdedb606c1..33f689c9330 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -991,6 +991,13 @@ class Log_event_writer
 public:
   ulonglong bytes_written;
   void *ctx;         ///< Encryption context or 0 if no encryption is needed
+  /*
+    The length of a checksum written at the end of the event, if any.
+    Currently this is always either 0, when checksums are disabled, or
+    BINLOG_CHECKSUM_LEN when using BINLOG_CHECKSUM_ALG_CRC32.
+    (If we ever add another checksum algorithm, we will need to instead store
+    here the algorithm to use instead of just the length).
+  */
   uint checksum_len;
   int write(Log_event *ev);
   int write_header(uchar *pos, size_t len);
@@ -1001,11 +1008,29 @@ class Log_event_writer
   void set_incident();
   void set_encrypted_writer()
   { encrypt_or_write= &Log_event_writer::encrypt_and_write; }
+  /*
+    Set a specific checksum setting. Used to ensure that
+    Format_description_log_event is always written with a checksum.
+  */
+  enum enum_binlog_checksum_alg set_checksum_alg(enum enum_binlog_checksum_alg 
alg)
+  {
+    /* Must be adapted to store the actual algorithm if we add another. */
+    enum enum_binlog_checksum_alg orig=
+      (checksum_len ? BINLOG_CHECKSUM_ALG_CRC32 : BINLOG_CHECKSUM_ALG_OFF);
+    checksum_len=
+      (alg != BINLOG_CHECKSUM_ALG_OFF && alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
+      BINLOG_CHECKSUM_LEN : 0;
+    return orig;
+  }
 
   Log_event_writer(IO_CACHE *file_arg, binlog_cache_data *cache_data_arg,
-                   Binlog_crypt_data *cr= 0)
+                   enum enum_binlog_checksum_alg checksum_alg,
+                   Binlog_crypt_data *cr)
     :encrypt_or_write(&Log_event_writer::write_internal),
     bytes_written(0), ctx(0),
+    checksum_len(( checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+                   checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
+                 BINLOG_CHECKSUM_LEN : 0),
     file(file_arg), cache_data(cache_data_arg), crypto(cr) { }
 
 private:
@@ -1323,7 +1348,9 @@ class Log_event
   }
 #else
   Log_event() : temp_buf(0), when(0), flags(0) {}
-  ha_checksum crc;
+  /* The checksum algorithm used (if any) when the event was read. */
+  enum enum_binlog_checksum_alg read_checksum_alg;
+  ha_checksum read_checksum_value;
   /* print*() functions are used by mysqlbinlog */
   virtual bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
   bool print_timestamp(IO_CACHE* file, time_t *ts = 0);
@@ -1405,16 +1432,6 @@ class Log_event
   static int read_log_event(IO_CACHE* file, String* packet,
                             const Format_description_log_event *fdle,
                             enum enum_binlog_checksum_alg checksum_alg_arg);
-  /* 
-     The value is set by caller of FD constructor and
-     Log_event::write_header() for the rest.
-     In the FD case it's propagated into the last byte 
-     of post_header_len[] at FD::write().
-     On the slave side the value is assigned from post_header_len[last] 
-     of the last seen FD event.
-  */
-  enum enum_binlog_checksum_alg checksum_alg;
-
   static void *operator new(size_t size)
   {
     extern PSI_memory_key key_memory_log_event;
@@ -1439,7 +1456,7 @@ class Log_event
   bool write_footer(Log_event_writer *writer)
   { return writer->write_footer(); }
 
-  my_bool need_checksum();
+  enum enum_binlog_checksum_alg select_checksum_alg();
 
   virtual bool write(Log_event_writer *writer)
   {
@@ -2877,8 +2894,15 @@ class Format_description_log_event: public 
Start_log_event_v3
   master_version_split server_version_split;
   const uint8 *event_type_permutation;
   uint32 options_written_to_bin_log;
+  /*
+    The checksum algorithm used in the binlog or relaylog following this
+    Format_description_event. Or BINLOG_CHECKSUM_ALG_UNDEF for a
+    Format_description_event which is not part of a binlog or relaylog file.
+  */
+  enum enum_binlog_checksum_alg used_checksum_alg;
 
-  Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
+  Format_description_log_event(uint8 binlog_ver, const char* server_ver= 0,
+      enum enum_binlog_checksum_alg checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF);
   Format_description_log_event(const uchar *buf, uint event_len,
                                const Format_description_log_event
                                *description_event);
diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc
index 4ae8bffcad7..a4d3ffae085 100644
--- a/sql/log_event_client.cc
+++ b/sql/log_event_client.cc
@@ -346,14 +346,14 @@ bool Log_event::print_header(IO_CACHE* file,
 
   /* print the checksum */
 
-  if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
-      checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+  if (read_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+      read_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
   {
     char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "%p "
     size_t const bytes_written=
-      my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08x ", crc);
+      my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08x ", 
read_checksum_value);
     if (my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib,
-                                          checksum_alg)) ||
+                                          read_checksum_alg)) ||
         my_b_printf(file, checksum_buf, bytes_written))
       goto err;
   }
@@ -1604,8 +1604,8 @@ bool Log_event::print_base64(IO_CACHE* file,
     uint tmp_size= size;
     Rows_log_event *ev= NULL;
     Log_event_type ev_type = (enum Log_event_type) ptr[EVENT_TYPE_OFFSET];
-    if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
-        checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
+    if (read_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
+        read_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
       tmp_size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the 
header
     switch (ev_type) {
       case WRITE_ROWS_EVENT:
@@ -1672,8 +1672,8 @@ bool Log_event::print_base64(IO_CACHE* file,
     Rows_log_event *ev= NULL;
     Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
 
-    if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
-        checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
+    if (read_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
+        read_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
       size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
 
     switch (et)
@@ -3680,7 +3680,7 @@ bool Write_rows_compressed_log_event::print(FILE *file,
   ulong len;
   bool is_malloc = false;
   if(!row_log_event_uncompress(glob_description_event,
-                               checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
+                               read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
                                temp_buf, UINT_MAX32, NULL, 0, &is_malloc,
                                &new_buf, &len))
   {
@@ -3717,7 +3717,7 @@ bool Delete_rows_compressed_log_event::print(FILE *file,
   ulong len;
   bool is_malloc = false;
   if(!row_log_event_uncompress(glob_description_event,
-                               checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
+                               read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
                                temp_buf, UINT_MAX32, NULL, 0, &is_malloc,
                                &new_buf, &len))
   {
@@ -3754,7 +3754,7 @@ Update_rows_compressed_log_event::print(FILE *file,
   ulong len;
   bool is_malloc= false;
   if(!row_log_event_uncompress(glob_description_event,
-                               checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
+                               read_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
                                temp_buf, UINT_MAX32, NULL, 0, &is_malloc,
                                &new_buf, &len))
   {
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index 5d07a6d853e..bee594291d6 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -574,8 +574,7 @@ int append_query_string(CHARSET_INFO *csinfo, String *to,
 **************************************************************************/
 
 Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
-  :log_pos(0), temp_buf(0), exec_time(0), thd(thd_arg),
-   checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
+  :log_pos(0), temp_buf(0), exec_time(0), thd(thd_arg)
 {
   server_id=   thd->variables.server_id;
   when=         thd->start_time;
@@ -599,7 +598,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool 
using_trans)
 
 Log_event::Log_event()
   :temp_buf(0), exec_time(0), flags(0), cache_type(EVENT_INVALID_CACHE),
-   thd(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
+   thd(0)
 {
   server_id=   global_system_variables.server_id;
   /*
@@ -737,82 +736,17 @@ void Log_event::init_show_field_list(THD *thd, 
List<Item>* field_list)
 }
 
 /**
-   A decider of whether to trigger checksum computation or not.
-   To be invoked in Log_event::write() stack.
-   The decision is positive 
-
-    S,M) if it's been marked for checksumming with @c checksum_alg
-    
-    M) otherwise, if @@global.binlog_checksum is not NONE and the event is 
-       directly written to the binlog file.
-       The to-be-cached event decides at @c write_cache() time.
-
-   Otherwise the decision is negative.
-
-   @note   A side effect of the method is altering Log_event::checksum_alg
-           it the latter was undefined at calling.
-
-   @return true   Checksum should be used. Log_event::checksum_alg is set.
-   @return false  No checksum
+   Select if and how to write checksum for an event written to the binlog.
+   It returns the actively configured binlog checksum option, unless the event
+   is being written to a cache (in which case the checksum, if any, is added
+   later when the cache is copied to the real binlog).
 */
-
-my_bool Log_event::need_checksum()
+enum enum_binlog_checksum_alg Log_event::select_checksum_alg()
 {
-  my_bool ret;
-  DBUG_ENTER("Log_event::need_checksum");
-
-  /* 
-     few callers of Log_event::write 
-     (incl FD::write, FD constructing code on the slave side, Rotate relay log
-     and Stop event) 
-     provides their checksum alg preference through Log_event::checksum_alg.
-  */
-  if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
-    ret= checksum_alg != BINLOG_CHECKSUM_ALG_OFF;
+  if (cache_type == Log_event::EVENT_NO_CACHE)
+    return (enum_binlog_checksum_alg)binlog_checksum_options;
   else
-  {
-    ret= binlog_checksum_options && cache_type == Log_event::EVENT_NO_CACHE;
-    checksum_alg= ret ? (enum_binlog_checksum_alg)binlog_checksum_options
-                      : BINLOG_CHECKSUM_ALG_OFF;
-  }
-  /*
-    FD calls the methods before data_written has been calculated.
-    The following invariant claims if the current is not the first
-    call (and therefore data_written is not zero) then `ret' must be
-    TRUE. It may not be null because FD is always checksummed.
-  */
-  
-  DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
-              data_written == 0);
-
-  DBUG_ASSERT(!ret || 
-              ((checksum_alg == binlog_checksum_options ||
-               /* 
-                  Stop event closes the relay-log and its checksum alg
-                  preference is set by the caller can be different
-                  from the server's binlog_checksum_options.
-               */
-               get_type_code() == STOP_EVENT ||
-               /* 
-                  Rotate:s can be checksummed regardless of the server's
-                  binlog_checksum_options. That applies to both
-                  the local RL's Rotate and the master's Rotate
-                  which IO thread instantiates via queue_binlog_ver_3_event.
-               */
-               get_type_code() == ROTATE_EVENT ||
-               get_type_code() == START_ENCRYPTION_EVENT ||
-               /* FD is always checksummed */
-               get_type_code() == FORMAT_DESCRIPTION_EVENT) && 
-               checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
-
-  DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
-
-  DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
-                get_type_code() != STOP_EVENT) ||
-               get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
-              cache_type == Log_event::EVENT_NO_CACHE);
-
-  DBUG_RETURN(ret);
+    return BINLOG_CHECKSUM_ALG_OFF;
 }
 
 int Log_event_writer::write_internal(const uchar *pos, size_t len)
@@ -959,8 +893,6 @@ bool Log_event::write_header(Log_event_writer *writer, 
size_t event_data_length)
                        (longlong) writer->pos(), event_data_length,
                        (int) get_type_code()));
 
-  writer->checksum_len= need_checksum() ? BINLOG_CHECKSUM_LEN : 0;
-
   /* Store number of bytes that will be written by this event */
   data_written= event_data_length + sizeof(header) + writer->checksum_len;
 
@@ -2609,7 +2541,6 @@ int Start_log_event_v3::do_apply_event(rpl_group_info 
*rgi)
 bool Format_description_log_event::write(Log_event_writer *writer)
 {
   bool ret;
-  bool no_checksum;
   /*
     We don't call Start_log_event_v3::write() because this would make 2
     my_b_safe_write().
@@ -2632,11 +2563,9 @@ bool 
Format_description_log_event::write(Log_event_writer *writer)
     FD_queue checksum_alg value.
   */
   compile_time_assert(BINLOG_CHECKSUM_ALG_DESC_LEN == 1);
-#ifdef DBUG_ASSERT_EXISTS
-  data_written= 0; // to prepare for need_checksum assert
-#endif
-  uint8 checksum_byte= (uint8)
-    (need_checksum() ? checksum_alg : BINLOG_CHECKSUM_ALG_OFF);
+  uint8 checksum_byte= (uint8) (used_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF 
?
+                                used_checksum_alg : BINLOG_CHECKSUM_ALG_OFF);
+  DBUG_ASSERT(used_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
   /* 
      FD of checksum-aware server is always checksum-equipped, (V) is in,
      regardless of @@global.binlog_checksum policy.
@@ -2650,17 +2579,16 @@ bool 
Format_description_log_event::write(Log_event_writer *writer)
      1 + 4 bytes bigger comparing to the former FD.
   */
 
-  if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
-  {
-    checksum_alg= BINLOG_CHECKSUM_ALG_CRC32;  // Forcing (V) room to fill 
anyway
-  }
+  enum enum_binlog_checksum_alg old_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
+  if (checksum_byte == BINLOG_CHECKSUM_ALG_OFF)
+    old_checksum_alg= writer->set_checksum_alg(BINLOG_CHECKSUM_ALG_CRC32);
   ret= write_header(writer, rec_size) ||
        write_data(writer, buff, sizeof(buff)) ||
        write_data(writer, post_header_len, number_of_event_types) ||
        write_data(writer, &checksum_byte, sizeof(checksum_byte)) ||
        write_footer(writer);
-  if (no_checksum)
-    checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
+  if (checksum_byte == BINLOG_CHECKSUM_ALG_OFF)
+    writer->set_checksum_alg(old_checksum_alg);
   return ret;
 }
 
@@ -5025,9 +4953,11 @@ int Create_file_log_event::do_apply_event(rpl_group_info 
*rgi)
   char *ext;
   int fd = -1;
   IO_CACHE file;
-  Log_event_writer lew(&file, 0);
-  int error = 1;
   Relay_log_info const *rli= rgi->rli;
+  enum enum_binlog_checksum_alg checksum_alg=
+    rli->relay_log.description_event_for_exec->used_checksum_alg;
+  Log_event_writer lew(&file, 0, checksum_alg, NULL);
+  int error = 1;
 
   THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
   bzero((char*)&file, sizeof(file));
diff --git a/sql/slave.cc b/sql/slave.cc
index 30ddb4949e8..08ac2e65779 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1795,11 +1795,13 @@ static int get_master_version_and_clock(MYSQL* mysql, 
Master_info* mi)
       break;
     case 3:
       mi->rli.relay_log.description_event_for_queue= new
-        Format_description_log_event(1, mysql->server_version);
+        Format_description_log_event(1, mysql->server_version,
+                                     mi->rli.relay_log.relay_log_checksum_alg);
       break;
     case 4:
       mi->rli.relay_log.description_event_for_queue= new
-        Format_description_log_event(3, mysql->server_version);
+        Format_description_log_event(3, mysql->server_version,
+                                     mi->rli.relay_log.relay_log_checksum_alg);
       break;
     default:
       /*
@@ -1811,7 +1813,8 @@ static int get_master_version_and_clock(MYSQL* mysql, 
Master_info* mi)
         master is 3.23, 4.0, etc.
       */
       mi->rli.relay_log.description_event_for_queue= new
-        Format_description_log_event(4, mysql->server_version);
+        Format_description_log_event(4, mysql->server_version,
+                                     mi->rli.relay_log.relay_log_checksum_alg);
       break;
     }
   }
@@ -1870,10 +1873,8 @@ static int get_master_version_and_clock(MYSQL* mysql, 
Master_info* mi)
 
     until it has received a new FD_m.
   */
-  mi->rli.relay_log.description_event_for_queue->checksum_alg=
-    mi->rli.relay_log.relay_log_checksum_alg;
 
-  DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg !=
+  DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->used_checksum_alg 
!=
               BINLOG_CHECKSUM_ALG_UNDEF);
   DBUG_ASSERT(mi->rli.relay_log.relay_log_checksum_alg !=
               BINLOG_CHECKSUM_ALG_UNDEF); 
@@ -2762,7 +2763,7 @@ static void write_ignored_events_info_to_relay_log(THD 
*thd, Master_info *mi)
     {
       DBUG_PRINT("info",("writing a Rotate event to track down ignored 
events"));
       rev->server_id= 0; // don't be ignored by slave SQL thread
-      if (unlikely(rli->relay_log.append(rev)))
+      if (unlikely(rli->relay_log.append(rev, 
rli->relay_log.relay_log_checksum_alg)))
         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
                    ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
                    "failed to write a Rotate event"
@@ -2775,7 +2776,7 @@ static void write_ignored_events_info_to_relay_log(THD 
*thd, Master_info *mi)
       DBUG_PRINT("info",("writing a Gtid_list event to track down ignored 
events"));
       glev->server_id= 0; // don't be ignored by slave SQL thread
       glev->set_artificial_event(); // Don't mess up Exec_Master_Log_Pos
-      if (unlikely(rli->relay_log.append(glev)))
+      if (unlikely(rli->relay_log.append(glev, 
rli->relay_log.relay_log_checksum_alg)))
         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
                    ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
                    "failed to write a Gtid_list event to the relay log, "
@@ -5961,7 +5962,7 @@ static int process_io_create_file(Master_info* mi, 
Create_file_log_event* cev)
           break;
         Execute_load_log_event xev(thd,0,0);
         xev.log_pos = cev->log_pos;
-        if (unlikely(mi->rli.relay_log.append(&xev)))
+        if (unlikely(mi->rli.relay_log.append(&xev, 
mi->rli.relay_log.relay_log_checksum_alg)))
         {
           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
                      ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -5975,7 +5976,7 @@ static int process_io_create_file(Master_info* mi, 
Create_file_log_event* cev)
       {
         cev->block = net->read_pos;
         cev->block_len = num_bytes;
-        if (unlikely(mi->rli.relay_log.append(cev)))
+        if (unlikely(mi->rli.relay_log.append(cev, 
mi->rli.relay_log.relay_log_checksum_alg)))
         {
           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
                      ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -5990,7 +5991,7 @@ static int process_io_create_file(Master_info* mi, 
Create_file_log_event* cev)
         aev.block = net->read_pos;
         aev.block_len = num_bytes;
         aev.log_pos = cev->log_pos;
-        if (unlikely(mi->rli.relay_log.append(&aev)))
+        if (unlikely(mi->rli.relay_log.append(&aev, 
mi->rli.relay_log.relay_log_checksum_alg)))
         {
           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
                      ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -6060,15 +6061,13 @@ static int process_io_rotate(Master_info *mi, 
Rotate_log_event *rev)
   */
   if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
   {
-    DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
+    
DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->used_checksum_alg ==
                 mi->rli.relay_log.relay_log_checksum_alg);
     
     delete mi->rli.relay_log.description_event_for_queue;
     /* start from format 3 (MySQL 4.0) again */
     mi->rli.relay_log.description_event_for_queue= new
-      Format_description_log_event(3);
-    mi->rli.relay_log.description_event_for_queue->checksum_alg=
-      mi->rli.relay_log.relay_log_checksum_alg;    
+      Format_description_log_event(3, NULL, 
mi->rli.relay_log.relay_log_checksum_alg);
   }
   /*
     Rotate the relay log makes binlog format detection easier (at next slave
@@ -6176,13 +6175,15 @@ static int queue_binlog_ver_1_event(Master_info *mi, 
const uchar *buf,
   }
   if (likely(!ignore_event))
   {
+    enum enum_binlog_checksum_alg checksum_alg=
+      mi->rli.relay_log.description_event_for_queue->used_checksum_alg;
     if (ev->log_pos)
       /*
          Don't do it for fake Rotate events (see comment in
       Log_event::Log_event(const char* buf...) in log_event.cc).
       */
       ev->log_pos+= event_len; /* make log_pos be the pos of the end of the 
event */
-    if (unlikely(rli->relay_log.append(ev)))
+    if (unlikely(rli->relay_log.append(ev, checksum_alg)))
     {
       delete ev;
       mysql_mutex_unlock(&mi->data_lock);
@@ -6208,6 +6209,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, 
const uchar *buf,
   ulong inc_pos;
   char *tmp_buf = 0;
   Relay_log_info *rli= &mi->rli;
+  enum enum_binlog_checksum_alg checksum_alg;
   DBUG_ENTER("queue_binlog_ver_3_event");
 
   /* read_log_event() will adjust log_pos to be end_log_pos */
@@ -6240,7 +6242,8 @@ static int queue_binlog_ver_3_event(Master_info *mi, 
const uchar *buf,
     break;
   }
 
-  if (unlikely(rli->relay_log.append(ev)))
+  checksum_alg= 
mi->rli.relay_log.description_event_for_queue->used_checksum_alg;
+  if (unlikely(rli->relay_log.append(ev, checksum_alg)))
   {
     delete ev;
     mysql_mutex_unlock(&mi->data_lock);
@@ -6342,7 +6345,7 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
   {
     // checksum behaviour is similar to the pre-checksum FD handling
     mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
-    mi->rli.relay_log.description_event_for_queue->checksum_alg=
+    mi->rli.relay_log.description_event_for_queue->used_checksum_alg=
       mi->rli.relay_log.relay_log_checksum_alg= checksum_alg=
       BINLOG_CHECKSUM_ALG_OFF;
   }
@@ -6471,8 +6474,7 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
         We detect this case by noticing a change of server_id and in this
         case likewise rollback the partially received event group.
       */
-      Format_description_log_event fdle(4);
-      fdle.checksum_alg= checksum_alg;
+      Format_description_log_event fdle(4, NULL, checksum_alg);
 
       /*
         Possible crash is flagged in being created FD' common header
@@ -6504,7 +6506,7 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
                             rev.new_log_ident);
       }
       mysql_mutex_lock(log_lock);
-      if (likely(!rli->relay_log.write_event(&fdle) &&
+      if (likely(!rli->relay_log.write_event(&fdle, checksum_alg) &&
                  !rli->relay_log.flush_and_sync(NULL)))
       {
         rli->relay_log.harvest_bytes_written(&rli->log_space_total);
@@ -6553,7 +6555,7 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
                            event_len - BINLOG_CHECKSUM_LEN);
       int4store(&rot_buf[event_len - BINLOG_CHECKSUM_LEN], rot_crc);
       DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
-      DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg 
==
+      
DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->used_checksum_alg ==
                   mi->rli.relay_log.relay_log_checksum_alg);
       /* the first one */
       DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
@@ -6573,7 +6575,7 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
         int4store(&rot_buf[EVENT_LEN_OFFSET],
                   uint4korr(&rot_buf[EVENT_LEN_OFFSET]) - BINLOG_CHECKSUM_LEN);
         DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
-        
DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
+        
DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->used_checksum_alg ==
                     mi->rli.relay_log.relay_log_checksum_alg);
         /* the first one */
         DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
@@ -6613,11 +6615,11 @@ static int queue_event(Master_info* mi, const uchar 
*buf, ulong event_len)
     tmp->copy_crypto_data(mi->rli.relay_log.description_event_for_queue);
     delete mi->rli.relay_log.description_event_for_queue;
     mi->rli.relay_log.description_event_for_queue= tmp;
-    if (tmp->checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
-      tmp->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
+    if (tmp->used_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
+      tmp->used_checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
 
     /* installing new value of checksum Alg for relay log */
-    mi->rli.relay_log.relay_log_checksum_alg= tmp->checksum_alg;
+    mi->rli.relay_log.relay_log_checksum_alg= tmp->used_checksum_alg;
 
     /*
       Do not queue any format description event that we receive after a
@@ -7182,7 +7184,8 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
       rli->relay_log.description_event_for_queue->created= 0;
       rli->relay_log.description_event_for_queue->set_artificial_event();
       if (rli->relay_log.append_no_lock
-          (rli->relay_log.description_event_for_queue))
+          (rli->relay_log.description_event_for_queue,
+           rli->relay_log.relay_log_checksum_alg))
         error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
       else
         rli->relay_log.harvest_bytes_written(&rli->log_space_total);
@@ -7195,7 +7198,8 @@ static int queue_event(Master_info* mi, const uchar *buf, 
ulong event_len)
       */
       Rotate_log_event fake_rev(mi->master_log_name, 0, mi->master_log_pos, 0);
       fake_rev.server_id= mi->master_id;
-      if (rli->relay_log.append_no_lock(&fake_rev))
+      if (rli->relay_log.append_no_lock(&fake_rev,
+                                        rli->relay_log.relay_log_checksum_alg))
         error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
       else
         rli->relay_log.harvest_bytes_written(&rli->log_space_total);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 8bde0f3bd53..69c4c9e889d 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -4267,7 +4267,7 @@ bool mysql_show_binlog_events(THD* thd)
 
     if (lex_mi->pos > BIN_LOG_HEADER_SIZE)
     {
-      checksum_alg= description_event->checksum_alg;
+      checksum_alg= description_event->used_checksum_alg;
       /* Validate user given position using checksum */
       if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
           checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc
index 5e1fa137fed..f71b1245bcc 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -236,7 +236,9 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void 
*rbr_buf,
 
   File file;
   IO_CACHE cache;
-  Log_event_writer writer(&cache, 0);
+  enum enum_binlog_checksum_alg checksum_alg=
+    (enum_binlog_checksum_alg) binlog_checksum_options;
+  Log_event_writer writer(&cache, 0, checksum_alg, NULL);
   Format_description_log_event *ev= 0;
 
   longlong thd_trx_seqno= (long long)wsrep_thd_trx_seqno(thd);
@@ -288,7 +290,7 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void 
*rbr_buf,
     to the dump file).
   */
   ev= (thd->wsrep_applier) ? wsrep_get_apply_format(thd) :
-    (new Format_description_log_event(4));
+    (new Format_description_log_event(4, NULL, checksum_alg));
 
   if (writer.write(ev) || my_b_write(&cache, (uchar*)rbr_buf, buf_len) ||
       flush_io_cache(&cache))
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 91abf1dffe8..0073f846ab3 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2150,16 +2150,16 @@ int wsrep_to_buf_helper(
     THD* thd, const char *query, uint query_len, uchar** buf, size_t* buf_len)
 {
   IO_CACHE tmp_io_cache;
-  Log_event_writer writer(&tmp_io_cache, 0);
+  enum enum_binlog_checksum_alg current_binlog_check_alg=
+    (enum_binlog_checksum_alg) binlog_checksum_options;
+  Log_event_writer writer(&tmp_io_cache, NULL, current_binlog_check_alg, NULL);
   if (open_cached_file(&tmp_io_cache, mysql_tmpdir, TEMP_PREFIX,
                        65536, MYF(MY_WME)))
     return 1;
   int ret(0);
-  enum enum_binlog_checksum_alg current_binlog_check_alg=
-    (enum_binlog_checksum_alg) binlog_checksum_options;
 
-  Format_description_log_event *tmp_fd= new Format_description_log_event(4);
-  tmp_fd->checksum_alg= current_binlog_check_alg;
+  Format_description_log_event *tmp_fd=
+    new Format_description_log_event(4, NULL, current_binlog_check_alg);
   writer.write(tmp_fd);
   delete tmp_fd;
 
@@ -2208,7 +2208,6 @@ int wsrep_to_buf_helper(
     Query_log_event ev(thd, thd->wsrep_TOI_pre_query,
                       thd->wsrep_TOI_pre_query_len,
                       FALSE, FALSE, FALSE, 0);
-    ev.checksum_alg= current_binlog_check_alg;
     if (writer.write(&ev)) ret= 1;
   }
 
@@ -2217,7 +2216,6 @@ int wsrep_to_buf_helper(
   /* WSREP GTID mode, we need to change server_id */
   if (wsrep_gtid_mode && !thd->variables.gtid_seq_no)
     ev.server_id= wsrep_gtid_server.server_id;
-  ev.checksum_alg= current_binlog_check_alg;
   if (!ret && writer.write(&ev)) ret= 1;
   if (!ret && wsrep_write_cache_buf(&tmp_io_cache, buf, buf_len)) ret= 1;
   close_cached_file(&tmp_io_cache);
-- 
2.30.2

_______________________________________________
commits mailing list -- commits@lists.mariadb.org
To unsubscribe send an email to commits-le...@lists.mariadb.org

Reply via email to