krowinski / php-mysql-replication

Pure PHP Implementation of MySQL replication protocol. This allow you to receive event like insert, update, delete with their data and raw SQL queries.
MIT License
319 stars 94 forks source link

GTID replication Return value of MySQLReplication\BinLog\BinLogCurrent::getBinFileName() must be of the type string, null returned #87

Open antonrubtsov opened 2 years ago

antonrubtsov commented 2 years ago

System details:

Problem

$eventInfo->getBinLogCurrent()->getBinFileName(); falls with Exception 'TypeError' with message 'Return value of MySQLReplication\BinLog\BinLogCurrent::getBinFileName() must be of the type string, null returned'

Steps required to reproduce the problem.

Starting conditions:

CREATE DATABASE test;
CREATE TABLE `test`.`test_table`
(
    `id`         bigint(20) NOT NULL AUTO_INCREMENT,
    `is_clicked` tinyint(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8;

Insert 1 string: insert into test.test_table (id, is_clicked) values (1,0); And run replication with GTID = ''

Reproducing error:

  1. update test.test_table set is_clicked = abs(is_clicked-1) where id = 1;
show master status ;
binlog.000005,21529,,,2b172ed7-1ad8-11ec-8570-0242ac12000e:1-100

var_dump($eventInfo->getBinlogCurrent);

  class MySQLReplication\BinLog\BinLogCurrent#85 (4) {
    private $binLogPosition =>
    int(21498)
    private $binFileName =>
    string(13) "binlog.000005"
    private $gtid =>
    string(40) "2b172ed7-1ad8-11ec-8570-0242ac12000e:100"
    private $mariaDbGtid =>
    NULL
  }
  1. Restart replication with GTID 2b172ed7-1ad8-11ec-8570-0242ac12000e:1-100
    class MySQLReplication\BinLog\BinLogCurrent#85 (4) {
    private $binLogPosition =>
    int(21498)
    private $binFileName =>
    NULL
    private $gtid =>
    string(40) "2b172ed7-1ad8-11ec-8570-0242ac12000e:100"
    private $mariaDbGtid =>
    NULL
    }

    Expected Result.

Actual Result.

Question

Is it a bug?

antonrubtsov commented 2 years ago

krowinski/php-mysql-replication/src/MySQLReplication/BinLog/BinLogSocketConnect.php:165

if ('' !== Config::getGtid()) {
    $this->setBinLogDumpGtid();
    $this->setBinLogDump(); // This change fixes the problem, but i'm not sure that it's correct.
} else {
         $this->setBinLogDump();
}

This change fixes the problem, but i'm not sure that it's correct.

krowinski commented 7 months ago

If you use gitid it will set just gtid if you use binlog file it will set binlog file Its intended but not changeable. I will change this in next version.