Giter Site home page Giter Site logo

krowinski / php-mysql-replication Goto Github PK

View Code? Open in Web Editor NEW
316.0 21.0 92.0 612 KB

Pure PHP Implementation of MySQL replication protocol. This allow you to receive event like insert, update, delete with their data and raw SQL queries.

License: MIT License

PHP 100.00%
php mysql-replication php-library mysql mysql-binlog mysql-replication-protocol replication binlog composer-packages events

php-mysql-replication's Introduction

php-mysql-replication

Latest Stable Version Total Downloads Latest Unstable Version Scrutinizer Code Quality Code Coverage

Pure PHP Implementation of MySQL replication protocol. This allows you to receive event like insert, update, delete with their data and raw SQL queries.

Based on a great work of creators:https://github.com/noplay/python-mysql-replication and https://github.com/fengxiangyun/mysql-replication

Installation

In you project

composer require krowinski/php-mysql-replication

or standalone

git clone https://github.com/krowinski/php-mysql-replication.git

composer install -o

Compatibility (based on integration tests)

PHP

  • php 8.2
  • php 8.3

MYSQL

  • mysql 5.5
  • mysql 5.6
  • mysql 5.7
  • mysql 8.0 (mysql_native_password and caching_sha2_password supported)
  • mariadb 5.5
  • mariadb 10.0
  • mariadb 10.1
  • probably percona versions as is based on native mysql

MySQL server settings

In your MySQL server configuration file you need to enable replication:

[mysqld]
server-id        = 1
log_bin          = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size  = 100M
binlog-format    = row #Very important if you want to receive write, update and delete row events

Mysql replication events explained https://dev.mysql.com/doc/internals/en/event-meanings.html

Mysql user privileges:

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'user'@'host';

GRANT SELECT ON `dbName`.* TO 'user'@'host';

Configuration

Use ConfigBuilder or ConfigFactory to create configuration. Available options:

'user' - your mysql user (mandatory)

'ip' or 'host' - your mysql host/ip (mandatory)

'password' - your mysql password (mandatory)

'port' - your mysql host port (default 3306)

'charset' - db connection charset (default utf8)

'gtid' - GTID marker(s) to start from (format 9b1c8d18-2a76-11e5-a26b-000c2976f3f3:1-177592)

'mariaDbGtid' - MariaDB GTID marker(s) to start from (format 1-1-3,0-1-88)

'slaveId' - script slave id for identification (default: 666) (SHOW SLAVE HOSTS)

'binLogFileName' - bin log file name to start from

'binLogPosition' - bin log position to start from

'eventsOnly' - array to listen on events (full list in ConstEventType.php file)

'eventsIgnore' - array to ignore events (full list in ConstEventType.php file)

'tablesOnly' - array to only listen on given tables (default all tables)

'databasesOnly' - array to only listen on given databases (default all databases)

'tableCacheSize' - some data are collected from information schema, this data is cached.

'custom' - if some params must be set in extended/implemented own classes

'heartbeatPeriod' - sets the interval in seconds between replication heartbeats. Whenever the master's binary log is updated with an event, the waiting period for the next heartbeat is reset. interval is a decimal value having the range 0 to 4294967 seconds and a resolution in milliseconds; the smallest nonzero value is 0.001. Heartbeats are sent by the master only if there are no unsent events in the binary log file for a period longer than interval.

'saveUuid' - sets slave uuid for identification (default: 0015d2b6-8a06-4e5e-8c07-206ef3fbd274)

Similar projects

Ruby: https://github.com/y310/kodama

Java: https://github.com/shyiko/mysql-binlog-connector-java

GO: https://github.com/siddontang/go-mysql

Python: https://github.com/noplay/python-mysql-replication

.NET: https://github.com/rusuly/MySqlCdc

Examples

All examples are available in the examples directory

This example will dump all replication events to the console:

Remember to change config for your user, host and password.

User should have replication privileges [ REPLICATION CLIENT, SELECT]

php example/dump_events.php

For test SQL events:

CREATE DATABASE php_mysql_replication;
use php_mysql_replication;
CREATE TABLE test4 (id int NOT NULL AUTO_INCREMENT, data VARCHAR(255), data2 VARCHAR(255), PRIMARY KEY(id));
INSERT INTO test4 (data,data2) VALUES ("Hello", "World");
UPDATE test4 SET data = "World", data2="Hello" WHERE id = 1;
DELETE FROM test4 WHERE id = 1;

Output will be similar to this (depends on configuration for example GTID off/on):

=== Event format description ===
Date: 2017-07-06T13:31:11+00:00
Log position: 0
Event size: 116
Memory usage 2.4 MB

=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803092
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13675
Memory usage 2.42 MB

=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803237
Event size: 145
Database: php_mysql_replication
Execution time: 0
Query: CREATE DATABASE php_mysql_replication
Memory usage 2.45 MB

=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803285
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13676
Memory usage 2.45 MB

=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803500
Event size: 215
Database: php_mysql_replication
Execution time: 0
Query: CREATE TABLE test4 (id int NOT NULL AUTO_INCREMENT, data VARCHAR(255), data2 VARCHAR(255), PRIMARY KEY(id))
Memory usage 2.45 MB

=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803548
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13677
Memory usage 2.45 MB

=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803637
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.45 MB

=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803708
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.71 MB

=== Event write ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803762
Event size: 54
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
    [0] => Array
        (
            [id] => 1
            [data] => Hello
            [data2] => World
        )

)

Memory usage 2.74 MB

=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803793
Event size: 31
Transaction ID: 662802
Memory usage 2.75 MB

=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803841
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13678
Memory usage 2.75 MB

=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803930
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.76 MB

=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804001
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.75 MB

=== Event update ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804075
Event size: 74
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
    [0] => Array
        (
            [before] => Array
                (
                    [id] => 1
                    [data] => Hello
                    [data2] => World
                )

            [after] => Array
                (
                    [id] => 1
                    [data] => World
                    [data2] => Hello
                )

        )

)

Memory usage 2.76 MB

=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804106
Event size: 31
Transaction ID: 662803
Memory usage 2.76 MB

=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804154
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13679
Memory usage 2.76 MB

=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804243
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.76 MB

=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804314
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.76 MB

=== Event delete ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804368
Event size: 54
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
    [0] => Array
        (
            [id] => 1
            [data] => World
            [data2] => Hello
        )

)

Memory usage 2.77 MB

=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804399
Event size: 31
Transaction ID: 662804
Memory usage 2.77 MB

Benchmarks

Tested on VM

Debian 8.7
PHP 5.6.30
Percona 5.6.35
inxi
CPU(s)~4 Single core Intel Core i5-2500Ks (-SMP-) clocked at 5901 Mhz Kernel~3.16.0-4-amd64 x86_64 Up~1 day Mem~1340.3/1996.9MB HDD~41.9GB(27.7% used) Procs~122 Client~Shell inxi~2.1.28
php example/benchmark.php
Start insert data
7442 event by seconds (1000 total)
7679 event by seconds (2000 total)
7914 event by seconds (3000 total)
7904 event by seconds (4000 total)
7965 event by seconds (5000 total)
8006 event by seconds (6000 total)
8048 event by seconds (7000 total)
8038 event by seconds (8000 total)
8040 event by seconds (9000 total)
8055 event by seconds (10000 total)
8058 event by seconds (11000 total)
8071 event by seconds (12000 total)

FAQ

  1. Why and when need php-mysql-replication ?

Well first of all MYSQL don't give you async calls. You usually need to program this in your application (by event dispatching and adding to some queue system and if your db have many point of entry like web, backend other microservices its not always cheap to add processing to all of them. But using mysql replication protocol you can listen on write events and process then asynchronously (the best combo it's to add item to some queue system like rabbitmq, redis or kafka). Also in invalidate cache, search engine replication, real time analytics and audits.

  1. It's awesome ! but what is the catch ?

Well first of all you need to know that a lot of events may come through, like if you update 1 000 000 records in table "bar" and you need this one insert from your table "foo" Then all must be processed by script, and you need to wait for your data. This is normal and this how it's work. You can speed up using config options. Also, if script crashes you need to save from time to time position form binlog (or gtid) to start from this position when you run this script again to avoid duplicates.

  1. I need to process 1 000 000 records and its taking forever!!

Like I mention in 1 point use queue system like rabbitmq, redis or kafka, they will give you ability to process data in multiple scripts.

  1. I have a problem ? you script is missing something ! I have found a bug !

Create an issue I will try to work on it in my free time :)

  1. How much its give overhead to MYSQL server ?

It work like any other MYSQL in slave mode and its giving same overhead.

  1. Socket timeouts error

To fix this best is to increase db configurations net_read_timeout and net_write_timeout to 3600. (tx Bijimon)

  1. Partial updates fix

Set in my.conf binlog_row_image=full to fix receiving only partial updates.

  1. No replication events when connected to replica server

Set in my.conf log_slave_updates=on to fix this (#71)(#66)

  1. "Big" updates / inserts

Default MYSQL setting generates one big blob of stream this require more RAM/CPU you can change this for smaller stream using variable binlog_row_event_max_size [https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html#sysvar_binlog_row_event_max_size] to split into smaller chunks

php-mysql-replication's People

Contributors

ale-blanco avatar dominiquegerber avatar dzunke avatar fengxiangyun avatar kobi97 avatar krowinski avatar limingxinleo avatar m-h-1 avatar matyx avatar misaert avatar mklepaczewski avatar rusuly avatar stern87 avatar wolaiye1010 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-mysql-replication's Issues

MySQLReplicationFactory constructor - no arguments

I'm not sure if this is intended, but I noticed that the examples are passing a Config object when creating a MySQLReplicationFactory object, but it doesn't look like the constructor for MySQLReplicationFactory is using it, as the constructor doesn't have any arguments. It looks like the constructor is always referencing a static instance of the Config object, which seems to be the last Config object created.

Notice: Undefined offset: -1

Hi

I am having this error:
Symfony\Component\Debug\Exception\ContextErrorException: Notice: Undefined offset: -1 (uncaught exception) at /var/www/html/salesforce-bridge/shared/vendor/krowinski/php-mysql-replication/src/MySQLReplication/Event/RowEvent/RowEvent.php line 372 while running console commandmy:task{"exception":"[object] (Symfony\\Component\\Debug\\Exception\\ContextErrorException(code: 0): Notice: Undefined offset: -1 at /var/www/html/salesforce-bridge/shared/vendor/krowinski/php-mysql-replication/src/MySQLReplication/Event/RowEvent/RowEvent.php:372)"}

Do you know why is this error raised? It looks like it's related with the ENUM fields, which I am using in my table, but apparently i don't get the error always but just some times.

Thanks,
Jury

Events not triggered with PRIMARY (statement) -> REPLICA (row) -> php-mysql-replication

  • Operating System: Debian
  • PHP Version: 7.4
  • php-mysql-replication Version: 6.2.4

Hello there,

We've got a running architecture of 1 primary (let's call it Bob) replicating to 10 replicas (new wording for master / slaves).
I'd like to watch for insert / update events with your package, but Bob currently replicates through the STATEMENT binlog format.

Since php-mysql-replication cannot work with this binlog format for insert / update events, I assumed that I could create an 11th replica just for this purpose (let's call it Alice), with its own binlog format set to ROW.

Problem is, when plugging php-mysql-replication on Alice:

  • If I perform insert / updates on Alice directly, insert / updates are triggered and catchable in PHP ✅
  • However, when performing insert / updates on Bob, nothing is triggered (tho data is properly replicated on Alice). 🚫

Assuming that binlog format cannot be changed on Bob (it's prod, running thousands of queries/s, replicating to datacenters locatedx on other continents) since it involves a high regression risk, do you know if I have a mean to solve this? Maybe I just missed some MySQL configuration?

FYI I performed my tests on dev servers, where Bob is a MariaDB 10.1.
On production, Bob is a MySQL 5.5 (I know... but I doubt that changes anything to the issue).
Prod and dev run on Debian. Alice runs MySQL 5.7 on Ubuntu.

Thank you,
Ben

Event Query:COMMIT and Event xid

Hi,
I tested the code on my ubuntu 14.04,and I sometimes got the
Event Query: COMMIT ,sometimes got Event xid;
would you mind explain the difference between the two events;
are they meaning of the end of a Transaction( for example : SQL statement: begin; insert .. update..or some other SQLs ; commit;)???
THANKS!!!

PHP Fatal error: Uncaught MySQLReplication\Socket\SocketException

Please provide the following details.

  • Operating System: Linux Ubuntu 18.4
  • PHP Version: 7.2
  • php-mysql-replication Version: 7.0
  • *mysql version (SELECT VERSION();): MySQL 8.0

Steps required to reproduce the problem.

  1. Connecting to replica
  2. Start consuming

Expected Result.

The replication application should work continuously, it works for sometimes and throws error.

Actual Result.

After running for few seconds, sometimes minutes it throws the following error;

PHP Fatal error: Uncaught MySQLReplication\Socket\SocketException: Success in /var/apps/nxo-fetcher-new/src/MySQLReplication/Socket/Socket.php:65
Stack trace:
#0 /var/apps/nxo-fetcher-new/src/MySQLReplication/BinLog/BinLogSocketConnect.php(63): MySQLReplication\Socket\Socket->readFromSocket(1273)
#1 /var/apps/nxo-fetcher-new/src/MySQLReplication/Event/Event.php(57): MySQLReplication\BinLog\BinLogSocketConnect->getResponse()
#2 /var/apps/nxo-fetcher-new/src/MySQLReplication/MySQLReplicationFactory.php(130): MySQLReplication\Event\Event->consume()
#3 /var/apps/nxo-fetcher-new/src/MySQLReplication/MySQLReplicationFactory.php(116): MySQLReplication\MySQLReplicationFactory->consume()
#4 /var/apps/nxo-fetcher-new/app/stream.php(78): MySQLReplication\MySQLReplicationFactory->run()
#5 {main}
thrown in /var/apps/nxo-fetcher-new/src/MySQLReplication/Socket/Socket.php on line 65

Event id is always same

Please provide the following details.

  • Operating System: Ubuntu 18.04
  • PHP Version: 7.2.4
  • php-mysql-replication Version: 7.0
  • *mysql version (SELECT VERSION();): 8

Steps required to reproduce the problem.

Read all the events

Expected Result.

Each event should have a unique id

Actual Result.

image

getDatetime2 not reads fsp when date is wrong

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 7.1
  • php-mysql-replication Version: 5.0.5
  • *mysql version (SELECT VERSION();): 5.7.26-log

Steps required to reproduce the problem.

  1. Have a table with column type DATETIME(6) NOT NULL - with fractional seconds
  2. Update any row and set value of this column to NULL
  3. Now you will receive an event that will fail when try to read value of any fields that go after mentioned above

Expected Result.

  • All data from binaryDataReader should go well after reading value from column with DATETIME(6) NOT NULL type

Actual Result.

  • binaryDataReader can't read next data because in the getDatetime2 function return null goes before it runs getFSP

Missing event values on Update

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 7.3.4
  • php-mysql-replication Version: 6.0.2
  • *mysql version (SELECT VERSION();): 5.7.27-30-log - Percona Server (GPL), Release 30, Revision 8916819

--

Steps required to reproduce the problem.

  1. git clone https://github.com/huangdijia/lumen-trigger-demo
  2. configure .env
  3. run php artisan trigger:start

Expected Result.

=== Event update === 
Date: 2019-09-06T14:38:28+08:00
Log position: 612816124
Event size: 394
Table: t8_ware_mall
Affected columns: 25
Changed rows: 1
Values: Array
(
    [0] => Array
        (
            [before] => Array
                (
                    [id] => 2346293598
                    [ware_title] =>  7250綠鑽=2500元 🌟C羅🌟可提供儲值帳單★正規代儲★所有面值都可儲
                    [ware_price] => 2500
                    [original_price] => 2500
                    [ware_number] => 994
                    [ware_desc] => 
                    [ware_validity] => 1568711354
                    [action_time] => 1566997245
                    [post_time] => 1544003695
                    [refresh_time] => 1566997245
                    [sell_user] => 2098159
                    [buy_user] => 0
                    [ware_type] => 8
                    [statu] => 0
                    [delete_time] => 1568711354
                    [is_auto] => 0
                    [game_id] => 22784
                    [server_id] => 22785
                    [card_id] => 1
                    [deliveryTime] => 5
                    [ware_currency] => 
                    [currency_company] => 0
                    [validityTime] => 30
                    [top_status] => 9999999
                    [mobile_status] => 9999999
                )

            [after] => Array
                (
                    [id] => 2346293598
                    [ware_title] =>  7250綠鑽=2500元 🌟C羅🌟可提供儲值帳單★正規代儲★所有面值都可儲
                    [ware_price] => 2500
                    [original_price] => 2500
                    [ware_number] => 993
                    [ware_desc] => 
                    [ware_validity] => 1568711354
                    [action_time] => 1566997245
                    [post_time] => 1544003695
                    [refresh_time] => 1566997245
                    [sell_user] => 2098159
                    [buy_user] => 0
                    [ware_type] => 8
                    [statu] => 0
                    [delete_time] => 1568711354
                    [is_auto] => 0
                    [game_id] => 22784
                    [server_id] => 22785
                    [card_id] => 1
                    [deliveryTime] => 5
                    [ware_currency] => 
                    [currency_company] => 0
                    [validityTime] => 30
             
       [top_status] => 9999999
                    [mobile_status] => 9999999
                )

        )

)

Memory usage 4.59 MB

Actual Result.

=== Event update === 
Date: 2019-09-06T14:41:46+08:00
Log position: 229744086
Event size: 56
Table: t8_ware_mall
Affected columns: 25
Changed rows: 1
Values: Array
(
    [0] => Array
        (
            [before] => Array
                (
                    [id] => 2349386924
                    [ware_title] => 
                    [ware_price] => 
                    [original_price] => 
                    [ware_number] => 
                    [ware_desc] => 
                    [ware_validity] => 
                    [action_time] => 
                    [post_time] => 
                    [refresh_time] => 
                    [sell_user] => 
                    [buy_user] => 
                    [ware_type] => 
                    [statu] => 
                    [delete_time] => 
                    [is_auto] => 
                    [game_id] => 
                    [server_id] => 
                    [card_id] => 
                    [deliveryTime] => 
                    [ware_currency] => 
                    [currency_company] => 
                    [validityTime] => 
                    [top_status] => 
                    [mobile_status] => 
                )

            [after] => Array
                (
                    [id] => 
                    [ware_title] => 
                    [ware_price] => 
                    [original_price] => 
                    [ware_number] => 934
                    [ware_desc] => 
                    [ware_validity] => 
                    [action_time] => 
                    [post_time] => 
                    [refresh_time] => 
                    [sell_user] => 
                    [buy_user] => 
                    [ware_type] => 
                    [statu] => 
                    [delete_time] => 
                    [is_auto] => 
                    [game_id] => 
                    [server_id] => 
                    [card_id] => 
                    [deliveryTime] => 
                    [ware_currency] => 
                    [currency_company] => 
                    [validityTime] => 
                    [top_status] => 
                    [mobile_status] => 
                )

        )

)

Memory usage 4.6 MB

Missing escaping of strings in \MySQLReplication\JsonBinaryDecoder\JsonBinaryDecoderService::parseScalar($type)

  • Operating System: Debian
  • PHP Version: 7.2
  • php-mysql-replication Version: 5.0.5
  • mysql version (SELECT VERSION();): 5.7.17 Percona

Steps required to reproduce the problem.

  1. Table with field type JSON
  2. Content like ["\"test"]

Expected Result.

  • RowEvent which contains the JSON-field with value ["\"test"].

Actual Result.

  • RowEvent which contains the JSON-field with invalid value [""test"].

I'll add a patch that fixes this issue.

Decoding of DECIMALS adds non significant trailing zeroes

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 7.4
  • php-mysql-replication Version: 7.0
  • mysql version 10.3.22-MariaDB-1:10.3.22+maria~bionic-log

Steps required to reproduce the problem (take from the unit tests)

CREATE TABLE test (test DECIMAL(20,10));
INSERT INTO test VALUES(-42000.123456);

Expected Result.

'-42000.123456'

Actual Result.

'-42000.1234560000'

Why this is a problem

Mathematically speaking, both results are valid. However decimals are represented using strings in the lib (bcmath). Hence, when tested for equality, '-42000.123456' is not the same as '-42000.1234560000'. Greater/Lower comparison do work, but not strict equality. The unit tests enforce the presence of these trailing zeroes, which to me should not be.

I can do a pull request to fix this if you agree with me that this is an issue. Not a big one, but still :)

Resume issue with big row events

  • Operating System: Not relevant
  • PHP Version: 7.4
  • php-mysql-replication Version: 7.0.1
  • mysql version: MySQL 5.7 / MySQL 8

Hello there,

We have a running application which:

  • Listens to MySQLReplication\Event\DTO\RowsDTO events (inserts, updates, deletes)
  • Loops over RowsDTO::getValues() to process them
  • After foreach ($rows->getValues()), stores the binlog position of the event: $event->getEventInfo()->getBinLogCurrent()->getBinFileName() / $event->getEventInfo()->getBinLogCurrent()->getBinLogPosition().

When the app starts, it starts from the previously stored filename / position.
In most of the times, this works well. However, we found a typical case when it doesn't.

Consider you have an INSERT containing several thousands rows (i.e. INSERT INTO [table] SELECT * FROM [some_other_table]). As opposed to what we expected, this doesn't fire a single RowsDTO event with a huge getValues() array, but several RowsDTO events with just a few dozens items in getValues() in each.

We didn't understood why, until we discovered the binlog_row_event_max_size option on the replica server, but that's not the point.

To reproduce:

  • Consider that before doing your big INSERT query, your position is 00001
  • Consider that position increments to 01000 at the end of the insert
  • Imagine that you stop your app in the middle of processing one of RowsDTO::getValues() event
  • Consider that you stored 00500 as the last processed position when you stopped the app (e.g. you have only processed half of the rows of that insert)
Expected Result:
  • When restarting the app, it should resume on position 00500 and trigger remaining RowsDTO events.
Actual Result:
  • Remaining RowsDTO events of that INSERT query are simply dismissed and apps resumes to the next query in the binlog.

The only solution we have right now is to pray that the application is not shut down (or doesn't crash) while processing that kind of big statements. We could increase binlog_row_event_max_size on the replica server but this won't guarantee RowsDTO won't be split and OTOH having a huge array in RowsDTO::getValues() might lead to memory issues.

As a quick fix, we now temporarily store filename / position on QueryDTO that are fired before and after the RowsDTO events, so that if not all RowsDTO can be processed, they can be replayed with the former position (00001 in our example). This leads to duplicate processing, but we prefer this instead of missing events.

Thank you,
Ben

Binlog-Event is to big - How to skip a binlog event?

  • Operating System: Linux
  • PHP Version: 7.2.8
  • php-mysql-replication Version: v5.0.4
  • mysql version: Percona 5.7.18

We have a binlog event that is larger than 1 GB and therefore receive the error message log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event 'mysql-bin.021114' at 2147481564, the last event read from '/var/log/mysql/mysql-bin.021114' at 123, the last byte read from '/var/log/mysql/mysql-bin.021114' at 2147481583..

Unfortunately, the values ​​for max_allowed_packet or slave_max_allowed_packet can not be set larger than 1 GB.

How can we solve the problem or skip the event?

Buffer Overflow at BinLogPosition

Please provide the following details.

  • Operating System:
  • PHP Version: < 7.0 >
  • php-mysql-replication Version: <1.0.0>
  • *mysql version (SELECT VERSION();): <10 Maria >

Steps required to reproduce the problem.

  1. Run the replication normally, let say using resume example
  2. binLogPosition exceed number 2147483647
  3. php-replication keep crashing due the int data type could not hold the binlog position number

Expected Result.

  • should be running without problem

Actual Result.

  • buffer overflow

Rewrite for php 7.1

As 5.6 is deprecated new code will be only for 7.1 >= so next version will be rewritten with strict + strong hinst

Cannot make a connection to a remote mysql server

  • Operating System: OS X
  • PHP Version: 7.1
  • php-mysql-replication Version: latest
  1. Remote server configuration:
$binLogStream = new MySQLReplicationFactory(
    (new ConfigBuilder())
        ->withUser('remote_user')
        ->withHost('101.1**.2**.1**')
        ->withPassword('password')
        ->withDatabasesOnly([
                'db_1'
        ])
        ->withTablesOnly([
                'tb_1'
        ])
        ->build()
);

Expected Result.

  • Event stream listening like example tested

Actual Result.
Please see the image below

reproduce

bug in update

Please provide the following details.

  • Operating System:
  • PHP Version: <7.3.9>
  • php-mysql-replication Version: <6.2>
  • *mysql version (SELECT VERSION();): <5.7.21-log >

Steps required to reproduce the problem.

CREATE TABLE `cache` (
  `key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `value` varchar(16100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'memory引擎不支持text',
  `expiration` int(11) NOT NULL,
  UNIQUE KEY `cache_key_unique` (`key`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

insert cache values ('laravel_cache5c785c036466adea360111aa28563bfd556b5fba','i:1','-1942153413')
3.
update cache set key='laravel_cache5c785c036466adea360111aa28563bfd556b5fba', value='i:2', expiration='1586248983'

Expected Result.

Date: 2020-04-07T16:42:03+08:00
Log position: 67042
Event size: 168
Table: cache
Affected columns: 3
Changed rows: 1
Values: Array
(
[0] => Array
(
[before] => Array
(
[key] => laravel_cache5c785c036466adea360111aa28563bfd556b5fba
[value] => i:1
[expiration] => -1942153413
)

        [after] => Array
            (
                [key] => laravel_cache5c785c036466adea360111aa28563bfd556b5fba
                [value] => i:2
                [expiration] => 1586248983
            )

    )

)

Actual Result.

Date: 2020-04-07T16:42:03+08:00
Log position: 67042
Event size: 168
Table: cache
Affected columns: 3
Changed rows: 1
Values: Array
(
[0] => Array
(
[before] => Array
(
[key] => laravel_cache5c785c036466adea360111aa28563bfd556b5fba
[value] => i:1
[expiration] => -1942153413
)

        [after] => Array
            (
                [key] => laravel_cache5c785c036466adea360111aa28563bfd556b5fbai:2;=?^?%9
                [value] => 
                [expiration] => 
            )

    )

)

Unable to start reading from a past point by using withBinLogPosition

I've also added a Question on Stackoverflow, link here:

I'm trying to use withBinLogPosition(..) when constructing the MYSQLReplicationFactory, as follows:

         $dbStream = new MySQLReplicationFactory(
            (new ConfigBuilder())
                ->withUser($userName)
                ->withPassword($password)
                ->withHost($hostName)
                ->withEventsOnly([
                    ConstEventType::UPDATE_ROWS_EVENT_V1, ConstEventType::UPDATE_ROWS_EVENT_V2,
                    ConstEventType::WRITE_ROWS_EVENT_V1, ConstEventType::WRITE_ROWS_EVENT_V2,
                    ConstEventType::DELETE_ROWS_EVENT_V1, ConstEventType::DELETE_ROWS_EVENT_V2,
                ])
                ->withSlaveId(9999)
                ->withBinLogPosition($binLogPosition)
                ->build()
        );
        // register benchmark subscriber handler
        $dbStream->registerSubscriber(new MysqlStreamEventSubscribers($logger));

In above piece of code, I've not specified withBinLogFileName(..). I assume specifying log file name to start with is not needed (correct if wrong?). When the value of $binLogPosition is something which has already been received, the above code does not replay from that log position onwards. I don't get any old records, just get any newer DB events. Any pointer to where I'm going wrong would be helpful.

unpack error

I have set GBK,

    $binLogStream = new MySQLReplicationFactory(
        (new ConfigBuilder())

.............
->withCharset('gbk')
->build()
);

but error still came out at
[ErrorException]
unpack(): Type I: not enough input, need 4, have 0

but when use utf8
it's
[ErrorException]
unpack(): Type i: not enough input, need 4, have 3

php 5.6 , centos 7 64bit mysql 5.6.16

binlog without database connection

is it possible to analyse binary logs without database (socket) connection?
Which classes I can use for?
Maybe with manual column name mapping.

Too many methods are private, very hard to extend

Greetings,

I've found too many of the properties and methods are private for me to usefully use or extend your library. When I want to make a quick change (i.e. backport ConstFieldType::DATETIME) into 1.x, I find that it takes an immense amount of work with respect to copy and pasting code just so i have access to the rowevent object that originally extended yours but slightly more logic in it.

Also, I do not want to use reflection but even if I did maintaining it is not tenable due to the sheer number of private properties.

I would argue the purpose of a library is to allow some modification but I cannot find that spirit in this library and the hopes I have for the future require me to hook into things such as getColumnData or tablemap, etc. It's a shame because this is really nice code but it's still not worth effort.

Even the config builder is too much of a burden to extend as the user that has permissions to repl data does not have access to information_schema.columns and I'd like to have it use two different connections for that but extending that requires extending all config/config* files, as well as repositories and factory file and the kicker is I need to copy and paste ALL of the code from those files because their properties are private!

Also the requirement of symfony 3.1 is tough, many libraries require 2 series and prevents an upgrade to your php-mysql-replication 2.x because of this. I understand some libraries need to lead the charge into newer symfonys, but this also prevents adoption.

PHP Fatal error: Uncaught exception 'MySQLReplication\BinLog\Exception\BinLogException' with message 'Unknown command' in /var/www/vendor/krowinski/php-mysql-replication/src/MySQLReplication/BinLog/BinLogSocketConnect.php:190

Hi,
When I run php example.php,the Exception occured.

PHP Fatal error:  Uncaught exception 'MySQLReplication\BinLog\Exception\BinLogException' with message 'Unknown command' in /var/www/vendor/krowinski/php-mysql-replication/src/MySQLReplication/BinLog/BinLogSocketConnect.php:190

Big/little endian assumptions.

Following code https://github.com/krowinski/php-mysql-replication/blob/master/src/MySQLReplication/BinaryDataReader/BinaryDataReader.php#L72 works by accident because s uses native architecture. And every Intel/AMD CPU is in little endian architecture which is the same as binlog bytes layout.

Architecture should be forced in unpack pattern ( s< - like in Perl, I'm not sure if PHP supports it).
Or native architecture should be checked and bytes reversed before unpacking in case of mismatch.

Error with socket

Please provide the following details.

  • Operating System: AWS Aurora RDS
  • PHP Version: 7.4
  • php-mysql-replication Version: 6.2.3
  • *mysql version (SELECT VERSION();): 5.6.10-log

Steps required to reproduce the problem.

Sometimes, I have got the following error "No error information" from the stack trace "/src/MySQLReplication/BinLog/BinLogSocketConnect.php(63): MySQLReplication\Socket\Socket->readFromSocket()"

Expected Result.

Actual Result.

I couldn't find some information to reproduce the problem.

Error while resuming with GTID

  • Operating System: Linux
  • PHP Version: 7.2
  • php-mysql-replication Version: <v6.0.0>
  • *mysql version 5.7.30 >

Steps required to reproduce the problem.

  1. Start replication with an executed gtid set provided using ConfigBuilder::withGtid($gtid_set). You should use an actual gtid set from your mysql master.

Expected Result.

  • Replication started from $gtid_set.

Actual Result.

  • Replication did not start. The following message appeared in the log:

The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. Replicate the missing transactions from elsewhere, or provision a new slave from backup. Consider increasing the master's binary log expiration period. The GTID sets and the missing purged transactions are too long to print in this message. For more information, please see the master's error log or the manual for GTID_SUBTRACT.

I've checked master's binlog, it contains required gtid_set.

require "symfony/event-dispatcher"

Sorry, my English is not good, I hope you can understand my description
This is the description of machine translation

php-mysql-replication Version*: ^6.2.0

file: MySQLReplication\Event\dispatch(EventDTO $eventDTO = null)
6.1.0 Version
$this->eventDispatcher->dispatch($eventDTO->getType(), $eventDTO);

^6.2.0 Version
$this->eventDispatcher->dispatch($eventDTO, $eventDTO->getType());

^6.2.0 Version composer.json require "symfony/event-dispatcher": "^3.1|^4.0|^5.0"
but ^3.1|^4.0 Method parameters
dispatch($eventName, Event $event = null)
It is different from the call mode

error info :Argument 2 passed to Symfony\Component\EventDispatcher\EventDispatcher::dispatch() must be an instance of Symfony\Component\EventDispatcher\Event or null, string given, called in /WMS/vendor/krowinski/php-mysql-replication/src/MySQLReplication/Event/Event.php on line 132[/WMS/vendor/symfony/event-dispatcher/EventDispatcher.php:36]

saving binlog filename

I'm trying to figure out how to save the current binlog filename when a script exits, so it can restart where it left off using the filename and position.

I see the binlog position comes in every event, and there is a Rotate event where you get the new binlog filename when the filename changes, but what if Rotate is never called and your script exits? Is there a way to pull the current binlog filename on connect or in every event?

Thanks for your help.

mysql 5.7x

Hi, i am running mysql 5.7.x the call $this->binaryDataReader->readIntBeBySize(5) in getDatetime2 return a negative. (datetime column)
PHP Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (10069-12-11 12:60:15) at position 12 (1): Double time specification' in C:\php-mysql-replication\src\MySQLReplication\Event\RowEvent\RowEvent.php:646
Stack trace:
#0 C:\php-mysql-replication\src\MySQLReplication\Event\RowEvent\RowEvent.php(646): DateTime->__construct('10069-12-11 12:...')
#1 C:\php-mysql-replication\src\MySQLReplication\Event\RowEvent\RowEvent.php(402): MySQLReplication\Event\RowEvent\RowEvent->getDatetime2(Array)
#2 C:\php-mysql-replication\src\MySQLReplication\Event\RowEvent\RowEvent.php(898): MySQLReplication\Event\RowEvent\RowEvent->getColumnData('\xFF')
#3 C:\php-mysql-replication\src\MySQLReplication\Event\Event.php(118): MySQLReplication\Event\RowEvent\RowEvent->makeUpdateRowsDTO()
#4 C:\php-mysql-replication\src\MySQLReplication\MySQLReplicationFactory.php(142): MySQLReplication\Event\Event->consume()
#5 C:\php-mysql-replication\example\dump_events.php(57): MySQLReplication\MySQLReplicat in C:\php-mysql-replication\src\MySQLReplication\Event\RowEvent\RowEvent.php on line 646

i was able to run https://github.com/noplay/python-mysql-replication
does it support MySQL 5.7.x ? thank you very much

Trancate Bug

If use the truncate, the event will not be recorded.

EOF packet not handled

  • Operating System: Linux
  • PHP Version: 7.1
  • php-mysql-replication Version: 5.0.1

Steps required to reproduce the problem.

  1. Start example/dump_events
  2. Restart replication server

Expected Result.

  • dump_events exits simply with "Disconnected by remote side" or similar exception

Actual Result.

  • Before "Disconnected by remote side" exception, there are a few "Warning: unpack(): Type C: not enough input, need 1, have 0" errors

Cause

On restart the replication server sends an EOF packet is sent. The Event::consume() method simply skips the first byte, assuming it is an OK byte and tries to unpack a full OK header - this fails, since the EOF packet is much shorter.


First of all, thanks for this library.

The issue is not that severe, since the script exits anyhow, but since the unpack errors came first in our logs, we thought that the replication server sent an illegal packet, and spent a few hours investigating in that direction.

Signature of \MySQLReplication\MySQLReplicationFactory::registerSubscriber()

\MySQLReplication\MySQLReplicationFactory::registerSubscriber() and \MySQLReplication\MySQLReplicationFactory::unregisterSubscriber() should require the interface \Symfony\Component\EventDispatcher\EventSubscriberInterface instead of \MySQLReplication\Event\EventSubscribers as the underlying event dispatcher methods \Symfony\Component\EventDispatcher\EventDispatcher::addSubscriber / \Symfony\Component\EventDispatcher\EventDispatcher::removeSubscriber do.

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

System details:

  • Operating System: ubuntu:18.04
  • PHP Version: <PHP 7.2.24-0ubuntu0.18.04.9 (cli)>
  • php-mysql-replication Version: <7.0.1>
  • *mysql version (SELECT VERSION();): <5.7.35-38-log PERCONA>

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.

  • binFileName = binlog.000005

Actual Result.

  • binFileName = NULL

Question

Is it a bug?

PHP 8.1: spammed with warnings

Great job, this is a very useful piece of code.
Small issue here with PHP 8.1:

  • Operating System: <Linux | Windows | OS X>
    Linux

  • PHP Version: <5.6 | 7.0 | ...>
    PHP 8.1

  • php-mysql-replication Version: <1.0.0>
    1.0.0

  • *mysql version
    Oracle-MYSQL 8.0.27

Steps required to reproduce the problem.

1. Run the dump_events.php
2. Get spammed by deprecated warnings

Expected Result.
Not get spammed by warnings

Actual Result.

Return type of MySQLReplication\Event\EventInfo::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /<path>/vendor/krowinski/php-mysql-replication/src/MySQLReplication/Event/EventInfo.php on line 100

How can support concurrent?

Run php-mysql-replication in swoole, I want consume events with concurrent, Can I do it like this?

// src/MySQLReplication/MySQLReplicationFactory.php:113

use Swoole\Coroutine;

    public function run(): void
    {
        while (1) {
            Coroutine::create(function () {
                $this->consume();
            });
        }
    }

[Insight] Usage of a function in loops should be avoided - in src/…/BinLog/BinLogConnect.php, line 162

in src/MySQLReplication/BinLog/BinLogConnect.php, line 162

This loop uses a function. To avoid the overhead of executing the function n times, you should precalculate it before the loop.

        }
        else
        {
            $error_code = unpack('v', $packet[1] . $packet[2])[1];
            $error_msg = '';
            for ($i = 9; $i < strlen($packet); $i++)
            {
                $error_msg .= $packet[$i];
            }

            throw new BinLogException($error_msg, $error_code);

Posted from SensioLabsInsight

Cannot see rows affected through triggers

Please provide the following details.

  • Operating System: Ubuntu 18.04
  • PHP Version: 7.2.24
  • php-mysql-replication Version: 6.2.4
  • *mysql version (SELECT VERSION();): MySQL 8

Steps required to reproduce the problem.

Happening all the time

Expected Result.

Tried using row, statement, mixed based events but cannot see rows inserted, updated, deleted by triggers

Actual Result.

No Events

Symfony 5.0 support?

do you plan to support Symfony 5?
"require": { "php": ">=7.1", "ext-sockets": "*", "ext-json": "*", "ext-bcmath": "*", "doctrine/dbal": "^2.5", "doctrine/collections": "^1.3", "symfony/event-dispatcher": "^2.8|^3.1|^4.0", "symfony/dependency-injection": "^2.8|^3.1|^4.0", "psr/simple-cache": "^1.0" },

No HeartbeatEvent on MySQL5.5.11

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 7.1.2
  • php-mysql-replication Version: v5.0.6
  • *mysql version (SELECT VERSION();): 服务器版本: 5.5.11-log - Source distribution

Steps required to reproduce the problem.

  1. git clone https://github.com/huangdijia/lumen-trigger-demo
  2. configure .env
  3. run php artisan trigger:start

Expected Result.

  • see HearbeatEvent
=== Event heartbeat === \n
Date: 1970-01-01T00:00:00+00:00\n
Log position: 218837\n
Event size: 33\n

Actual Result.

  • No HeartbeatEvent, But Other Event Like write, update, delete Normal.

Normal on other version of mysql

Events not being captured on Percona Cluster

Please provide the following details.

  • Operating System: Linux (CentOS 7)
  • PHP Version: 7.4.9
  • php-mysql-replication Version: 6.2
  • mysql version: 5.7.30-33-57-log Percona XtraDB Cluster (GPL), Release rel33, Revision 5dd6d59, WSREP version 31.43, wsrep_31.43

Steps required to reproduce the problem.

  1. Test example/dump_events.php

Expected Result.

  • output of mysql DB events.

Actual Result.

  • only heartbeat events returned.

I've tested this same solution on my local system using a regular install of MySQL. When I moved to test on my production system, the events are not propagating as expected. My concern is that the version of Percona Cluster we're using is at fault, and I'm curious if there are any ideas on how to address.

We have a 3 node cluster. I'm attempting to run the php-mysql-replication application on our 3rd node.

I've added the server config (of the node that is not working) below for reference:

mysql> SHOW variables WHERE variable_name LIKE "%binlog%";
+--------------------------------------------+----------------------+
| Variable_name                              | Value                |
+--------------------------------------------+----------------------+
| binlog_cache_size                          | 32768                |
| binlog_checksum                            | CRC32                |
| binlog_direct_non_transactional_updates    | OFF                  |
| binlog_error_action                        | ABORT_SERVER         |
| binlog_format                              | ROW                  |
| binlog_group_commit_sync_delay             | 0                    |
| binlog_group_commit_sync_no_delay_count    | 0                    |
| binlog_gtid_simple_recovery                | ON                   |
| binlog_max_flush_queue_time                | 0                    |
| binlog_order_commits                       | ON                   |
| binlog_row_image                           | FULL                 |
| binlog_rows_query_log_events               | OFF                  |
| binlog_skip_flush_commands                 | OFF                  |
| binlog_space_limit                         | 0                    |
| binlog_stmt_cache_size                     | 32768                |
| binlog_transaction_dependency_history_size | 25000                |
| binlog_transaction_dependency_tracking     | COMMIT_ORDER         |
| encrypt_binlog                             | OFF                  |
| have_backup_safe_binlog_info               | YES                  |
| innodb_api_enable_binlog                   | OFF                  |
| innodb_locks_unsafe_for_binlog             | OFF                  |
| log_statements_unsafe_for_binlog           | ON                   |
| max_binlog_cache_size                      | 18446744073709547520 |
| max_binlog_files                           | 0                    |
| max_binlog_size                            | 1073741824           |
| max_binlog_stmt_cache_size                 | 18446744073709547520 |
| sync_binlog                                | 1                    |
| wsrep_forced_binlog_format                 | NONE                 |
+--------------------------------------------+----------------------+
28 rows in set (0.00 sec)
mysql> SHOW variables WHERE variable_name LIKE "server_%";
+----------------+--------------------------------------+
| Variable_name  | Value                                |
+----------------+--------------------------------------+
| server_id      | 3                                    |
| server_id_bits | 32                                   |
| server_uuid    | 4fe64515-be6b-11e9-8e7f-026f00293d26 |
+----------------+--------------------------------------+
3 rows in set (0.00 sec)

When the application is run, I only receive heartbeat events, even though I am 100% other activity is happening across the cluster (I do occasionally get "format description" events, but I'm not terribly sure what these are for). I have yet to see any of the important events like updates, writes, or deletes.

{
    "type": "format description",
    "eventInfo": {
        "timestamp": 1598513185,
        "type": 15,
        "id": 3,
        "size": 119,
        "pos": 0,
        "flag": 0,
        "checkSum": true,
        "sizeNoHeader": null,
        "dateTime": null,
        "binLogCurrent": {
            "binLogPosition": 11890,
            "binFileName": "mysql-bin.000016",
            "gtid": null,
            "mariaDbGtid": null
        }
    },
    "subject": null,
    "arguments": null
}{
    "type": "heartbeat",
    "eventInfo": {
        "timestamp": 0,
        "type": 27,
        "id": 3,
        "size": 39,
        "pos": 11890,
        "flag": 0,
        "checkSum": true,
        "sizeNoHeader": null,
        "dateTime": null,
        "binLogCurrent": {
            "binLogPosition": 11890,
            "binFileName": "mysql-bin.000016",
            "gtid": null,
            "mariaDbGtid": null
        }
    },
    "subject": null,
    "arguments": null
}{
    "type": "heartbeat",
    "eventInfo": {
        "timestamp": 0,
        "type": 27,
        "id": 3,
        "size": 39,
        "pos": 11890,
        "flag": 0,
        "checkSum": true,
        "sizeNoHeader": null,
        "dateTime": null,
        "binLogCurrent": {
            "binLogPosition": 11890,
            "binFileName": "mysql-bin.000016",
            "gtid": null,
            "mariaDbGtid": null
        }
    },
    "subject": null,
    "arguments": null
}

EDIT: additional note; it looks like that each heartbeat event is identical while the application is running. The binlog position and file never changes. Not sure if this is helpful information or not, but thought I should include it.

Exception: Could not find first log file name in binary log index file (bad filename)

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 7.1
  • php-mysql-replication Version: v6.2.0
  • *mysql version (SELECT VERSION();): 10.3.21-MariaDB-1:10.3.21+maria~stretch-log

Steps required to reproduce the problem.

  1. Start a listener
  2. Trigger events
  3. CTRL-C to quit the listener
  4. Start the listener again

Expected Result.

  • Continue listening from last position

Actual Result.

  • Exception: Could not find first log file name in binary log index file. The filename always contains non-printable characters at the end "mysql-bin.007566ݬ�p". Does not always happen. But 3 out of 5 attempts will cause this issue.

mysql5.7 binlog_format = mixed has some bug i think

mysql5.7 binlog_format = mixed :

when I execute "UPDATE hj_access SET access_type = '/appver1' WHERE hj_access.id = 1"

dump_event.php output :
"UPDATE hj_access SET access_type = '/appver1' WHERE hj_access.id = 1�0�w"

I think the length pass to BinaryDataReader->read() has something wrong.
but binlog_format = row seems to be right.

[ErrorException] unpack(): Type i:

I came across a fetal error:

[ErrorException]
unpack(): Type i: not enough input, need 4, have 2

only in src/MySQLReplication/BinLog/BinLogServerInfo.php there are same function call,

self::$serverInfo['connection_id'] = unpack('I', $data[$i] . $data[++$i] . $data[++$i] . $data[++$i])[1];

Handling of negative DECIMAL numbers (mariadb) seems erronous

Please provide the following details.

  • Operating System: Linux
  • PHP Version: 8.0
  • php-mysql-replication Version: 1.0.0
  • *mysql version : 10.3.22-MariaDB-1:10.3.22+maria~bionic-log mariadb.org binary distribution

Steps required to reproduce the problem.

CREATE TABLE test(field DECIMAL(11,4));
INSERT INTO TEST(-57.1234);

Actual Result.

In RowEvent.php line 665:

bcmul(): Argument #1 ($num1) is not well-formed

I have taken a look at the "RowEvent" where the fault occurs. Printing out the offending argument shows that it is indeed malformed : -57.-1234. The negative is applied to both integral and fractional parts, hence the problem. Removing the XOR of the value didn't solve the issue completely, so I "abs" the values and this worked.

I don't know the intricacies of binlogs good enough to be sure that my fix is good —tbh the ABS() seems like a hack to me...— but if it is I can make a pull request for it to be integrated into the project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.