Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding replication protocol support to mysql server implementation #759

Merged
merged 15 commits into from
Jan 16, 2023

Conversation

Fizic
Copy link
Contributor

@Fizic Fizic commented Dec 22, 2022

No description provided.

feat: method in BinlogStreamer, work with replication protocol in server package
feat: all methods for replication protocol
mysql/errcode.go Outdated Show resolved Hide resolved
@Fizic Fizic marked this pull request as draft December 22, 2022 14:04
@lance6716
Copy link
Collaborator

Hi @Fizic is this PR still a draft?

@Fizic Fizic marked this pull request as ready for review December 29, 2022 07:06
replication/binlogstreamer.go Outdated Show resolved Hide resolved
server/command.go Outdated Show resolved Hide resolved
server/command.go Outdated Show resolved Hide resolved
return &p, nil
}

func parseBinlogDumpGTID(data []byte) (*mysql.MysqlGTIDSet, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you plan to support MariaDB GTID set? you can see ParseMariadbGTID

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MariaDB doesn't implement COM_BINLOG_DUMP_GTID - so, we can assume that this message sent by MySQL.

https://github.com/MariaDB/server/blob/10.9/include/mysql_com.h#L118

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I mean if there's not too much work to do we can support MariaDB by the way. But as you said MariaDB does not use COM_BINLOG_DUMP_GTID so it may not be a trivial work

server/resp.go Outdated Show resolved Hide resolved
server/resp.go Outdated Show resolved Hide resolved
server/resp.go Show resolved Hide resolved
server/command.go Show resolved Hide resolved
replication/binlogstreamer.go Show resolved Hide resolved
s := replication.NewBinlogStreamer()
go h.HandleBinlogDump(pos, s)

return s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another choice is that this Conn never returns, we directly call writeBinlogEvents in a loop. I'm not sure what should we do if the Conn is returned and MySQL client send another command to this connection

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting question. mysql-clients can be disconnected when they are not responsive (see net_write_timeout and net_read_timeout). We should check how replication protocol works.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reminding us, there're two questions

  1. I wrongly thought the connection will be re-used for next command at first, and want to remind author to check what's the behaviour if the connection is both serving a binlog stream and client's request. Now I see writeBinlogEvents won't do that.
  2. mysql client may set heartbeat interval and binlog streamer should append heartbeat event when the stream is idle for the interval. I think it's OK to implement it later because some use case of this feature will not let stream be idle for a long time.

//handle Replication command
HandleRegisterSlave(data []byte) error
HandleBinlogDump(pos *Position, s *replication.BinlogStreamer)
HandleBinlogDumpGTID(gtidSet *MysqlGTIDSet, s *replication.BinlogStreamer)
Copy link

@ostinru ostinru Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that s *replication.BinlogStreamer shouldn't be here. It is up to users who will implement ReplicationHandler what to do with these events.

PS: feel free to disagree

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don't understand, you mean we can expose Conn to user and user directly write binlog event as []byte to Conn?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... I worded it really badly.

I will agree with you that it is not a good idea to expose Conn.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency we can

  • move s *replication.BinlogStreamer to return values
  • add error to return values
  • remove go in Conn.dispatch()... or document that this method will be called form its own coroutine.

}

func (h EmptyReplicationHandler) HandleBinlogDumpGTID(gtidSet *MysqlGTIDSet, r *replication.BinlogStreamer) {
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding r.close() here, just to gracefully release resources.

}
return nil
} else {
return fmt.Errorf("the handler does not support replication protocol, use ReplicationHandler instead")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is better to fall back to

return c.h.HandleOtherCommand(cmd, data)

Copy link
Collaborator

@lance6716 lance6716 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rest lgtm

and I remember mysqlbinlog can actively stop a binlog stream https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html#option_mysqlbinlog_stop-never I'm not sure the termination is done at client-side or server-side so need we implement more behaviour. We can do it later.

server/replication.go Outdated Show resolved Hide resolved
server/replication.go Show resolved Hide resolved
Copy link
Collaborator

@lance6716 lance6716 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have more comments @ostinru @atercattus

@ostinru
Copy link

ostinru commented Jan 12, 2023

👍 Looks good to me

@lance6716 lance6716 merged commit 3dc80ac into go-mysql-org:master Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants