Skip to content

Conversation

huangjunwen
Copy link
Contributor

@huangjunwen huangjunwen commented Jan 31, 2020

This pr adds more meta data added after MySQL-8.0:

GTIDEvent:

  • immediate/original commit timestamp for this trx
  • transaction length (in bytes) for all binlog events of this trx, including this GTIDEvent. This is useful to detect transaction boundry
  • immediate/original server version

TableMapEvent:

  • column names
  • primary key info
  • signedness info for numeric columns
  • collation info for character and enum/set columns
  • geometry type info

These can be hopefully to solve #427 if using MySQL-8.0

Example GTIDEvent dump (MySQL-8.0):

=== GTIDEvent === Date: 2020-02-01 19:15:26 Log position: 3440812 Event size: 88 Commit flag: 1 GTID_NEXT: 5aa72a7f-44a8-11ea-947f-0242ac190002:55 LAST_COMMITTED: 54 SEQUENCE_NUMBER: 55 Immediate commmit timestamp: 1580555726309342 (2020-02-01T19:15:26.309342+08:00) Orignal commmit timestamp: 0 (<n/a>) Transaction length: 197 Immediate server version: 80019 Orignal server version: 0 

Example GTIDEvent dump for the same event (MySQL-5.7):

=== GTIDEvent === Date: 2020-02-01 19:15:26 Log position: 15156 Event size: 65 Commit flag: 1 GTID_NEXT: 5aa72a7f-44a8-11ea-947f-0242ac190002:55 LAST_COMMITTED: 49 SEQUENCE_NUMBER: 50 Immediate commmit timestamp: 0 (<n/a>) Orignal commmit timestamp: 0 (<n/a>) Transaction length: 0 Immediate server version: 0 Orignal server version: 0 

Example TableMapEvent dump (MySQL-8.0):

=== TableMapEvent === Date: 2020-03-10 15:24:58 Log position: 78747 Event size: 580 TableID: 118 TableID size: 6 Flags: 1 Schema: test Table: _types Column count: 42 Column type: 00000000 10 01 01 02 09 03 08 f6 04 05 01 02 09 03 08 f6 |................| 00000010 04 05 0d 0a 13 13 12 12 11 11 fe 0f fe 0f fc fc |................| 00000020 fc fc fc fc fc fc fe fe ff f5 |..........| NULL bitmap: 00000000 00 00 fc c0 ff 03 |......| Signedness bitmap: 00000000 00 7f 80 |...| Default charset: [] Column charset: [224 224 63 63 63 63 63 63 224 224 224 224] Set str value: [[1 2]] Enum str value: [[a b]] Column name: [b_bit n_boolean n_tinyint n_smallint n_mediumint n_int n_bigint n_decimal n_float n_double nu_tinyint nu_smallint nu_mediumint nu_int nu_bigint nu_decimal nu_float nu_double t_year t_date t_time t_ftime t_datetime t_fdatetime t_timestamp t_ftimestamp c_char c_varchar c_binary c_varbinary c_tinyblob c_blob c_mediumblob c_longblob c_tinytext c_text c_mediumtext c_longtext e_enum s_set g_geometry j_json] Geometry type: [0] Primary key: [] Primary key prefix: [] Enum/set default charset: [224] Enum/set column charset: [] 

Example TableMapEvent dump for the same event (MySQL-5.7):

=== TableMapEvent === Date: 2020-03-10 15:24:58 Log position: 31058 Event size: 133 TableID: 117 TableID size: 6 Flags: 1 Schema: test Table: _types Column count: 42 Column type: 00000000 10 01 01 02 09 03 08 f6 04 05 01 02 09 03 08 f6 |................| 00000010 04 05 0d 0a 13 13 12 12 11 11 fe 0f fe 0f fc fc |................| 00000020 fc fc fc fc fc fc fe fe ff f5 |..........| NULL bitmap: 00000000 00 00 fc c0 ff 03 |......| Signedness bitmap: Default charset: [] Column charset: [] Set str value: [] Enum str value: [] Column name: [] Geometry type: [] Primary key: [] Primary key prefix: [] Enum/set default charset: [] Enum/set column charset: [] 

ref:

@IANTHEREAL
Copy link
Collaborator

Cool! We will take a look ASAP @huangjunwen

@IANTHEREAL
Copy link
Collaborator

@csuzhangxc @WangXiangUSTC This pr enhances the mysql 8.0 binlog replication protocol, PTAL

@siddontang
Copy link
Collaborator

can you help us test it for MariaDB 8.0? @huangjunwen

@huangjunwen
Copy link
Contributor Author

ok, i will check the compatibility of MariaDB later

Copy link
Contributor

@csuzhangxc csuzhangxc left a comment

Choose a reason for hiding this comment

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

cool, rest LGTM.
BTW, can you add some unit tests?

mysql/util.go Outdated
case 1:
u |= uint64(b[0])
default:
panic(fmt.Errorf("BytesToUint64 byte slice length must be in range [1, 8]"))
Copy link
Contributor

Choose a reason for hiding this comment

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

How about returning an error instead of panic as other func did in this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem

LastCommitted int64
SequenceNumber int64

// The followings are available only after MySQL-8.0
Copy link
Contributor

Choose a reason for hiding this comment

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

How about adding more details about these fields? (OriginalCommitTimestamp and OriginalCommitTimestamp were introduced in 8.0.1, TransactionLength was introduced in 8.0.2, ImmediateServerVersion and OriginalServerVersion were introduced in 8.0.14).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem

continue
}

if collation, ok := collations[p]; ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use collations[i] here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm... i and p are two different counters in this loop: i is the index of all columns while p is the index of character columns, here is an example to illustrate:

column i p
a int 0 n/a
b char(8) 1 0
c bigint 2 n/a
d char(8) 3 1
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 you're right, I found The column index is counted only in all character columns. now.

@huangjunwen
Copy link
Contributor Author

cool, rest LGTM.
BTW, can you add some unit tests?

Sure, i'd like to add some unit tests for both mysql and mariadb once i have time.

@siddontang
Copy link
Collaborator

can we merge it now? @GregoryIan @csuzhangxc

@csuzhangxc
Copy link
Contributor

I think we can merge it, and address comments later (in another PR) or let them go.

@huangjunwen
Copy link
Contributor Author

huangjunwen commented Mar 7, 2020

Would you like to wait a while, i'm starting to write tests this morning ...

@IANTHEREAL
Copy link
Collaborator

👍 yep, we wait for your test case. This is very worthwhile, especially when encountering enum and set types, collation map will be wrong.

@IANTHEREAL
Copy link
Collaborator

@huangjunwen Cool, we will take a look ASAP

@huangjunwen
Copy link
Contributor Author

I've removed types-related helper methods in TableMapEvent now. This is because these types-related optional meta data is stored in a compact format: for example, signedness bitmap only stores the signedness of numeric fields, default charset/column charset only stores collation id of character fields...

If we want to reconstruct the mapping of column index -> meta (signedness/collation id, ...), we need to know whether the field is considerred as a numeric field or a character field ... But there are many corner cases here, more investigation is needed to implement correctly. So i've decided not to implement them in this pr and open another issue to track this later.

Copy link
Contributor

@csuzhangxc csuzhangxc left a comment

Choose a reason for hiding this comment

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

LGTM

@IANTHEREAL
Copy link
Collaborator

LGTM Cool, let's make it perfect later

@dhlin
Copy link
Contributor

dhlin commented Mar 19, 2020

Hi @GregoryIan @siddontang What do we expect on the commit standard in a PR to merge?
I saw there are some commits seem to be draft:

Move some code.
Remove unneccesary code.

and some merge commits

Merge branch 'master' of github.com:huangjunwen/go-mysql
Merge branch 'master' into master

These commits are essential but they can be organized and cleaned before the merge, do we bother to do so?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants