Bug #115976 Inserting multiple rows into a table without a primary key fails.
Submitted: 2 Sep 2:54 Modified: 2 Sep 7:03
Reporter: xilin Chen Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:8.0.39 OS:Any
Assigned to: CPU Architecture:Any

[2 Sep 2:54] xilin Chen
Description:
Under binlog_row_image=minamal configuration, inserting multiple rows into a table without a primary key fails. 

Receive an error: Writing one row to the row-based binary log failed

How to repeat:
First modify the configuration:
binlog_format=row
binlog_row_image=minimal

Then create a table without a primary key:
create table t(id int);

The last time you insert multiple rows:
insert into t values(),();

Receive an error: Writing one row to the row-based binary log failed

Success after changing the parameter binlog_row_image to full
[2 Sep 7:03] MySQL Verification Team
Hello xilin Chen,

Thank you for the report and test case.
Verified as described.

regards,
Umesh
[15 Oct 7:12] huahua xu
Hi xilin Chen:

Suggested fix:

diff --git a/sql/binlog.cc b/sql/binlog.cc
index c27af25..3a93b2c 100644
--- a/sql/binlog.cc
+++ b/sql/binlog.cc
@@ -10870,7 +10870,7 @@ Rows_log_event *THD::binlog_prepare_pending_rows_event(
 
   Rows_log_event *pending = binlog_get_pending_rows_event(is_transactional);
 
-  if (unlikely(pending && !pending->is_valid())) return nullptr;
+  if (unlikely(pending && !pending->is_valid() && pending->get_row_count() <= 0)) return nullptr;
 
   /*
     Check if the current event is non-NULL and a write-rows
@@ -10886,7 +10886,7 @@ Rows_log_event *THD::binlog_prepare_pending_rows_event(
     have the same setting for partial json updates, because
     partialness of json can only be changed outside transactions.
   */
-  if (!pending || pending->server_id != serv_id ||
+  if (!pending || !pending->is_valid() || pending->server_id != serv_id ||
       pending->get_table_id() != table->s->table_map_id ||
       pending->get_general_type_code() != general_type_code ||
       pending->get_data_size() + needed > binlog_row_event_max_size ||
diff --git a/sql/log_event.h b/sql/log_event.h
index cfbbfd9..94cf2bc 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -2742,6 +2742,8 @@ class Rows_log_event : public virtual binary_log::Rows_event, public Log_event {
 
   uint m_row_count; /* The number of rows added to the event */
 
+  uint get_row_count() { return m_row_count; }
+
  protected:
   /*
      The constructors are protected since you're supposed to inherit