Bug #101533 Purge binlog in instance startup cause Previous_gtids wrong in new binlog file
Submitted: 10 Nov 2020 6:31 Modified: 9 Mar 12:42
Reporter: ggwdwsbs W Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:8.0, 8.0.22 OS:Any
Assigned to: CPU Architecture:Any

[10 Nov 2020 6:31] ggwdwsbs W
Description:
When binlog initializing in instance startup stage,  the new binlog file is created before the purge_logs_before_date(), but the init_gtid_sets() and write prev gtids event to new binlog file are executed after purge binlog. 

If all previous binlog files are purged in purge_logs_before_date(), the Previous_gtids event in new binlog file will be empty, which is wrong because it should contain all gtids  executed before.

It may cause errors in replication.

This bug is related to Bug #101421, https://bugs.mysql.com/bug.php?id=101421. They are cause by similar reason.

How to repeat:
Using following test cause to repeat.

purge_cause_wrong_previous_gtids-master.opt

--log-bin=mysql-bin
--binlog-format=row
--enforce_gtid_consistency=on
--gtid-mode=on
--binlog_expire_logs_seconds=1

purge_cause_wrong_previous_gtids.test

set gtid_next= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1';
create database test1;
set gtid_next= default;
--source include/restart_mysqld.inc
show binlog events in "mysql-bin.000002";
drop database test1;

The expected result is

set gtid_next= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1';
create database test1;
set gtid_next= default;
# restart
show binlog events in "mysql-bin.000002";
Log_name        Pos     Event_type      Server_id       End_log_pos     Info
mysql-bin.000002        4       Format_desc     1       125     Server ver: 8.0.22-rds-dev-debug, Binlog ver: 4
mysql-bin.000002        125     Previous_gtids  1       196     aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1
drop database test1;

The reject file the case produced is 

set gtid_next= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1';
create database test1;
set gtid_next= default;
# restart
show binlog events in "mysql-bin.000002";
Log_name        Pos     Event_type      Server_id       End_log_pos     Info
mysql-bin.000002        4       Format_desc     1       125     Server ver: 8.0.22-rds-dev-debug, Binlog ver: 4
mysql-bin.000002        125     Previous_gtids  1       156
drop database test1;

Suggested fix:
Switch the position of purge_logs_before_date and gtid init in init_server_components. Do purge_logs_before_date lastly.
[10 Nov 2020 7:11] MySQL Verification Team
Hello!

Thank you for the report and feedback.

regards,
Umesh
[9 Mar 12:42] Margaret Fisher
Posted by developer:
 
Changelog entry added for MySQL 8.0.24:

If all previous binary log files were purged at startup because their retention period had expired, the new binary log file contained an empty Previous_gtids event, which could cause errors in replication. The order of initialization has now been changed so that previous binary log files are only purged after the previous GTID set has been written to the new binary log file that is created at startup.