зеркало из https://github.com/github/vitess-gh.git
183 строки
6.0 KiB
Go
183 строки
6.0 KiB
Go
/*
|
|
Copyright 2019 The Vitess Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
// Package mysql is a library to support MySQL binary protocol,
|
|
// both client and server sides. It also supports binlog event parsing.
|
|
package mysql
|
|
|
|
/*
|
|
|
|
Implementation notes, collected during coding.
|
|
==============================================
|
|
|
|
The reference for the capabilities is at this location:
|
|
http://dev.mysql.com/doc/internals/en/capability-flags.html
|
|
|
|
--
|
|
CLIENT_FOUND_ROWS
|
|
|
|
The doc says:
|
|
Send found rows instead of affected rows in EOF_Packet.
|
|
Value
|
|
0x00000002
|
|
|
|
We just pass it through to the server.
|
|
|
|
--
|
|
CLIENT_CONNECT_WITH_DB:
|
|
|
|
It drives the ability to connect with a database name.
|
|
The server needs to send this flag if it supports it.
|
|
If the client supports it as well, and wants to connect with a database name,
|
|
then the client can set the flag in its response, and then put the database name
|
|
in the handshake response.
|
|
|
|
If the server doesn't support it (meaning it is not set in the server
|
|
capability flags), then the client may set the flag or not (as the
|
|
server should ignore it anyway), and then should send a COM_INIT_DB
|
|
message to set the database.
|
|
|
|
--
|
|
PLUGGABLE AUTHENTICATION:
|
|
|
|
See https://dev.mysql.com/doc/internals/en/authentication-method-mismatch.html
|
|
for more information on this.
|
|
|
|
Our server side always starts by using mysql_native_password, like a
|
|
real MySQL server.
|
|
|
|
Our client will expect the server to always use mysql_native_password
|
|
in its initial handshake. This is what a real server always does, even though
|
|
it's not technically mandatory.
|
|
|
|
The server's AuthServer plugin method AuthMethod() will then return
|
|
what auth method the server wants to use. If it is
|
|
mysql_native_password, and the client already returned the data, we
|
|
use it. Otherwise we switch the auth to what the server wants (by
|
|
sending an Authentication Method Switch Request packet) and
|
|
re-negotiate.
|
|
|
|
--
|
|
Maximum Packet Size:
|
|
|
|
Set to zero by client and ignored by the server. Not sure what to do
|
|
with this now. It seems the mysql client is sending 16777216 to the
|
|
server, which is what we use anyway. Not sure any client will send any
|
|
lower value, and if they do, not sure what the first 3 bytes of a
|
|
packet should be (still 0xff 0xff 0xff or the max packet size).
|
|
|
|
--
|
|
CLIENT_CONNECT_ATTRS
|
|
|
|
The client can send up optional connection attributes with this flags.
|
|
I don't see a use for them yet.
|
|
|
|
--
|
|
Multi result sets:
|
|
|
|
Only used by stored procedures returning multiple result sets.
|
|
Unclear if it is also used when the CLIENT_MULTI_STATEMENTS flag is used.
|
|
See: http://dev.mysql.com/doc/internals/en/multi-resultset.html
|
|
|
|
The flags returned is then used to mark if there are more result sets
|
|
coming up.
|
|
|
|
We do not support any of this yet. It would be nice to plumb that for
|
|
ExecuteBatch later on though.
|
|
|
|
--
|
|
Character sets:
|
|
|
|
See: http://dev.mysql.com/doc/internals/en/character-set.html#packet-Protocol::CharacterSet
|
|
|
|
We maintain a map of character set names to integer value.
|
|
|
|
--
|
|
Server protection:
|
|
|
|
We should add the following protections for the server:
|
|
- Limit the number of concurrently opened client connections.
|
|
- Add an idle timeout and close connections after that timeout is reached.
|
|
Should start during initial handshake, maybe have a shorter value during
|
|
handshake.
|
|
|
|
--
|
|
NUM_FLAG flag:
|
|
|
|
It is added by the C client library if the field is numerical.
|
|
|
|
if (IS_NUM(client_field->type))
|
|
client_field->flags|= NUM_FLAG;
|
|
|
|
This is somewhat useless. Also, that flag overlaps with GROUP_FLAG
|
|
(which seems to be used by the server only for temporary tables in
|
|
some cases, so it's not a big deal).
|
|
|
|
But eventually, we probably want to remove it entirely, as it is not
|
|
transmitted over the wire. For now, we keep it for backward
|
|
compatibility with the C client.
|
|
|
|
--
|
|
Row-based replication:
|
|
|
|
The following types or constructs are not yet supported by our RBR:
|
|
|
|
- in MariaDB, the type TIMESTAMP(N) where N>0 is stored in the row the
|
|
exact same way as TIMESTAMP(0). So there is no way to get N, except
|
|
by knowing the table exact schema. This is such a corner case. MySQL
|
|
5.6+ uses TIMESTAMP2, and uses metadata to know the precision, so it
|
|
works there very nicely.
|
|
|
|
From mariaDB source code comment:
|
|
'So row-based replication between temporal data types of
|
|
different precision is not possible in MariaDB.'
|
|
|
|
- JSON is stored as an optimized index data blob in the row. We don't
|
|
parse it to re-print a text version for re-insertion. Instead, we
|
|
just return NULL. So JSOn is not supported.
|
|
|
|
Replication Notes:
|
|
==================
|
|
|
|
This package also defines a few data structures used for replication.
|
|
It is meant to only depend on the proto definitions, and nothing else.
|
|
Replication support has two main aspects:
|
|
|
|
1. Replication event and positions.
|
|
|
|
A replication event is an individual event, and it has an ID, called GTID.
|
|
|
|
A replication position is defined slightly differently for MariaDB and MySQL 5.6+:
|
|
|
|
- MariaDB uses the latest position as an integer, that assumes every
|
|
single event before that integer was applied. So a replication
|
|
position is similar to a GTID.
|
|
|
|
- Mysql 5.6+ keeps track of all event ever applied, in a structure called GTIDSet.
|
|
|
|
To make these two compatible, a replication position is defined by
|
|
this library as a GTIDSet. For MariaDB, the Set is equal to a Position.
|
|
|
|
|
|
2. Binlog event management. They are defined in the MySQL spec at:
|
|
http://dev.mysql.com/doc/internals/en/replication-protocol.html
|
|
|
|
These are slightly different for MariaDB and MySQL 5.6+, as they
|
|
contain GTIDs. MariaDB also defines a GTID event that has an implicit
|
|
Begin, that can replace an usual Begin.
|
|
|
|
*/
|