diff --git a/composer.json b/composer.json index cae9b1c..e7fe3b9 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "krowinski/php-mysql-replication", + "name": "hetao29/php-mysql-replication", "description": "Pure PHP Implementation of MySQL replication protocol. This allow you to receive event like insert, update, delete with their data and raw SQL queries.", "keywords": [ "mysql-replication", @@ -17,7 +17,7 @@ "ext-json": "*", "ext-sockets": "*", "doctrine/collections": "^2.1", - "doctrine/dbal": "^3.8", + "doctrine/dbal": "^4.0", "psr/log": "^3.0", "psr/simple-cache": "^3.0", "symfony/event-dispatcher": "^6.0|^7.0" @@ -26,7 +26,7 @@ "kubawerlos/php-cs-fixer-custom-fixers": "^3.19", "monolog/monolog": "^3.5", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.5", + "phpunit/phpunit": "^11.0", "symplify/easy-coding-standard": "^12.1" }, "license": "MIT", diff --git a/src/MySQLReplication/BinLog/BinLogSocketConnect.php b/src/MySQLReplication/BinLog/BinLogSocketConnect.php index 9b097b9..68578c5 100644 --- a/src/MySQLReplication/BinLog/BinLogSocketConnect.php +++ b/src/MySQLReplication/BinLog/BinLogSocketConnect.php @@ -192,9 +192,14 @@ private function getBinlogStream(): void $this->executeSQL('SET @master_binlog_checksum = @@global.binlog_checksum'); } + if ($this->config->heartbeatPeriod > 0.00) { // master_heartbeat_period is in nanoseconds - $this->executeSQL('SET @master_heartbeat_period = ' . $this->config->heartbeatPeriod * 1000000000); + if(version_compare($this->repository->getVersion(),"8.4.0")>=0){ + $this->executeSQL('SET @source_heartbeat_period = ' . $this->config->heartbeatPeriod * 1000000000); + }else{ + $this->executeSQL('SET @master_heartbeat_period = ' . $this->config->heartbeatPeriod * 1000000000); + } $this->logger->debug('Heartbeat period set to ' . $this->config->heartbeatPeriod . ' seconds'); } diff --git a/src/MySQLReplication/BinaryDataReader/BinaryDataReader.php b/src/MySQLReplication/BinaryDataReader/BinaryDataReader.php index 3a8119f..ca521ee 100644 --- a/src/MySQLReplication/BinaryDataReader/BinaryDataReader.php +++ b/src/MySQLReplication/BinaryDataReader/BinaryDataReader.php @@ -114,16 +114,21 @@ public function readUInt24(): int return $data[1] + ($data[2] << 8) + ($data[3] << 16); } - public function readUInt64(): string + public function readUInt64(): string|int { return $this->unpackUInt64($this->read(self::UNSIGNED_INT64_LENGTH)); } - public function unpackUInt64(string $binary): string + public function unpackUInt64(string $binary): string|int { $data = self::unpack('V*', $binary); - return bcadd((string)$data[1], bcmul((string)$data[2], bcpow('2', '32'))); + $num = bcadd((string)$data[1], bcmul((string)$data[2], bcpow('2', '32'))); + if($num>PHP_INT_MAX || $numread(self::UNSIGNED_INT64_LENGTH)); - return bcadd((string)$data[1], (string)($data[2] << 32)); + $num = bcadd((string)$data[1], (string)($data[2] << 32)); + if($num>PHP_INT_MAX || $numunpackUInt64($this->read(self::UNSIGNED_INT48_LENGTH) . chr(0) . chr(0)); + return (string)$this->unpackUInt64($this->read(self::UNSIGNED_INT48_LENGTH) . chr(0) . chr(0)); } public function isComplete(int $size): bool diff --git a/src/MySQLReplication/Event/RotateEvent.php b/src/MySQLReplication/Event/RotateEvent.php index 0e0d2b9..58f3118 100644 --- a/src/MySQLReplication/Event/RotateEvent.php +++ b/src/MySQLReplication/Event/RotateEvent.php @@ -13,7 +13,7 @@ class RotateEvent extends EventCommon { public function makeRotateEventDTO(): RotateDTO { - $binFilePos = $this->binaryDataReader->readUInt64(); + $binFilePos = (string)$this->binaryDataReader->readUInt64(); $binFileName = $this->binaryDataReader->read( $this->eventInfo->getSizeNoHeader() - $this->getSizeToRemoveByVersion() ); diff --git a/src/MySQLReplication/Event/RowEvent/RowEvent.php b/src/MySQLReplication/Event/RowEvent/RowEvent.php index e2f27ee..d5cbf77 100644 --- a/src/MySQLReplication/Event/RowEvent/RowEvent.php +++ b/src/MySQLReplication/Event/RowEvent/RowEvent.php @@ -416,7 +416,7 @@ public function makeUpdateRowsDTO(): ?UpdateRowsDTO protected function findTableMap(): ?TableMap { - $tableId = $this->binaryDataReader->readTableId(); + $tableId = (string)$this->binaryDataReader->readTableId(); $this->binaryDataReader->advance(2); if (in_array( diff --git a/src/MySQLReplication/Event/XidEvent.php b/src/MySQLReplication/Event/XidEvent.php index 39611fa..a59f981 100644 --- a/src/MySQLReplication/Event/XidEvent.php +++ b/src/MySQLReplication/Event/XidEvent.php @@ -13,6 +13,6 @@ class XidEvent extends EventCommon { public function makeXidDTO(): XidDTO { - return new XidDTO($this->eventInfo, $this->binaryDataReader->readUInt64()); + return new XidDTO($this->eventInfo, (string)$this->binaryDataReader->readUInt64()); } } diff --git a/src/MySQLReplication/MySQLReplicationFactory.php b/src/MySQLReplication/MySQLReplicationFactory.php index 59e9604..43391ba 100644 --- a/src/MySQLReplication/MySQLReplicationFactory.php +++ b/src/MySQLReplication/MySQLReplicationFactory.php @@ -33,11 +33,11 @@ class MySQLReplicationFactory public function __construct( Config $config, - RepositoryInterface $repository = null, - CacheInterface $cache = null, - EventDispatcherInterface $eventDispatcher = null, - SocketInterface $socket = null, - LoggerInterface $logger = null + RepositoryInterface|null $repository = null, + CacheInterface|null $cache = null, + EventDispatcherInterface|null $eventDispatcher = null, + SocketInterface|null $socket = null, + LoggerInterface|null $logger = null ) { $config->validate(); diff --git a/src/MySQLReplication/Repository/MySQLRepository.php b/src/MySQLReplication/Repository/MySQLRepository.php index ee7a779..19d9ec7 100644 --- a/src/MySQLReplication/Repository/MySQLRepository.php +++ b/src/MySQLReplication/Repository/MySQLRepository.php @@ -57,21 +57,21 @@ public function isCheckSum(): bool public function getVersion(): string { - $r = ''; - $versions = $this->getConnection() - ->fetchAllAssociative('SHOW VARIABLES LIKE "version%"'); - - foreach ($versions as $version) { - $r .= $version['Value']; - } + $res = $this->getConnection() + ->fetchAssociative('SHOW VARIABLES LIKE "version"'); - return $r; + return $res['Value']??""; } public function getMasterStatus(): MasterStatusDTO { - $data = $this->getConnection() - ->fetchAssociative('SHOW MASTER STATUS'); + if(version_compare($this->getVersion(),"8.4.0")>=0){ + $data = $this->getConnection() + ->fetchAssociative('SHOW BINARY LOG STATUS'); + }else{ + $data = $this->getConnection() + ->fetchAssociative('SHOW MASTER STATUS'); + } if (empty($data)) { throw new BinLogException( MySQLReplicationException::BINLOG_NOT_ENABLED, diff --git a/tests/Unit/Repository/MySQLRepositoryTest.php b/tests/Unit/Repository/MySQLRepositoryTest.php index 5ad88ac..d126124 100644 --- a/tests/Unit/Repository/MySQLRepositoryTest.php +++ b/tests/Unit/Repository/MySQLRepositoryTest.php @@ -70,22 +70,14 @@ public function testShouldIsCheckSum(): void public function testShouldGetVersion(): void { - $expected = [ - [ - 'Value' => 'foo', - ], - [ - 'Value' => 'bar', - ], - [ - 'Value' => '123', - ], - ]; + $expected = [ + 'Value' => 'version', + ]; - $this->connection->method('fetchAllAssociative') - ->willReturn($expected); + $this->connection->method('fetchAssociative') + ->willReturn($expected); - self::assertEquals('foobar123', $this->mySQLRepositoryTest->getVersion()); + self::assertEquals('version', $this->mySQLRepositoryTest->getVersion()); } public function testShouldGetMasterStatus(): void