Patch: https://lists.mariadb.org/hyperkitty/list/commits@lists.mariadb.org/thread/QCTK775G3SFVGFGDZGLYSNNGSCWMTVFG/
The direct cause of this is that the particular REPLACE INTO () VALUES (), () causes a special case where a write rows event is binlogged with a zero-length after-image. At some point in the history, the code was changed so that m_rows_buf is not allocated when not needed, but is_valid() was not updated to reflect this, so is_valid() incorrectly returns false for this write rows event. And this causes the failure when the second () is binlogged as an update rows event which ends up checking is_valid() for the prior write rows event.
So this looks like a regression, though I did not spend the effort to research the commit history to discover exactly which version it was introduced in. There are a number of other places in the code where it explicitly handles the case that the after image can be empty like this.
Patch: https://lists.mariadb.org/hyperkitty/list/commits@lists.mariadb.org/thread/QCTK775G3SFVGFGDZGLYSNNGSCWMTVFG/
The direct cause of this is that the particular REPLACE INTO () VALUES (), () causes a special case where a write rows event is binlogged with a zero-length after-image. At some point in the history, the code was changed so that m_rows_buf is not allocated when not needed, but is_valid() was not updated to reflect this, so is_valid() incorrectly returns false for this write rows event. And this causes the failure when the second () is binlogged as an update rows event which ends up checking is_valid() for the prior write rows event.
So this looks like a regression, though I did not spend the effort to research the commit history to discover exactly which version it was introduced in. There are a number of other places in the code where it explicitly handles the case that the after image can be empty like this.