mysql 通信模块_MySQL · 源码分析 · 网络通信模块浅析

mysql> create table t1 (a int, b int);

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values (1,1),(2,2);

Query OK, 2 rows affected (0.00 sec)

当执行最后一条select操作时,这里使用的类为Protocol_classic

发送metadata

ref: Protocol_classic::start_result_metadata

将列的个数写入Net缓冲区

ref: Protocol_classic::send_field_metadata

逐列的准备元数据信息,包含:

| 3bytes 标识符:def

| db_name

| table_name

| org_table_name

| col_name

| org_col_name

| 字符集编码

| 列长度

| 列类型

| flags

| decimals(这里为0)

| 预留

| 预留

可以看到每个列的元数据都包含了非常多的信息,使用字符串存储,这也意味着对于一条简单的SQL,你的网络传输的内容可能大多数都是元数据,即时你的客户端可能并不需要引用到。

有多个列就写多个packet到Net buffer (Protocol_classic::end_row)

ref: Protocol_classic::end_result_metadata

write_eof_packet函数会被调用,用于标识元数据信息到此结束。此处共写5个字节(不含packet header)

发送数据

●ref: end_send --> Protocol_classic::end_row

如上例,发送两行数据的packet包括

1

‘1’

1

‘1’

1

‘2’

1

‘2’

结束发送

ref: THD::send_statement_status -->net_send_eof --> write_eof_packet

发送结果结束标记,其中包含了sql执行过程中产生的warning个数

元数据开销

从上述可以看到,结果集中有很大一部分的开销是给元数据的,这意味着类似普通的pk查询,元数据的开销可能会非常昂贵。

以下贴下我之前测试过的一个例子,增加了几个选项来控制发送的元数据量:

0/METADATA_FULL: return all metadata, default value.

1/METADATA_REAL_COLUMN: only column name;

2/METADATA_FAKE_COLUMN: fake column name ,use 1,2...N instead of real column name

3/METADATA_NULL_COLUMN: use NULL to express the metadata information

4/METADATA_IGNORE: ignore metadata information, just for test..

测试表:

CREATE TABLE `test_meta_impact` (

`abcdefg1` int(11) NOT NULL AUTO_INCREMENT,

`abcdefg2` int(11) DEFAULT NULL,

`abcdefg3` int(11) DEFAULT NULL,

`abcdefg4` int(11) DEFAULT NULL,

……

……

`abcdefg40` int(11) DEFAULT NULL,

PRIMARY KEY (`abcdefg1`)

) ENGINE=InnoDB AUTO_INCREMENT=229361 DEFAULT CHARSET=utf8

使用mysqlslap测试并发pk查询

mysqlslap --no-defaults -uxx --create-schema=test -h$host -P $port --number-of-queries=1000000000 --concurrency=100 --query='SELECT * FROM test.test_meta_impact where abcdefg1 = 2'

测试结果

METADATA_FULL : 3.48w TPS, Net send 113M

METADATA_REAL_COLUMN: 7.2W TPS, Net send 111M

METADATA_FAKE_COLUMN: 9.2W TPS , Net send 116M

METADATA_NULL_COLUMN: 9.6w TPS , Net send 115M

METADATA_IGNORE: 13.8w TPS, Net send 30M

很显然无论网络流量还是TPS吞吐量,在这个人为构造的极端场景下,元数据的开销都非常的显著。

来源:数据库内核月

原文:http://mysql.taobao.org/monthly/2016/07/04/

如有侵权或不周之处,敬请劳烦联系若飞(微信:1321113940)马上删除,谢谢!

·END·

架构师

我们都是架构师!

架构师订阅号,关注获取更多技术分享

现已开通多个微信群,有兴趣交流学习的同学

可加若飞微信:1321113940进群

合作邮箱:admin@137x.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值