Giter Site home page Giter Site logo

tcpcollect's Introduction

mysqlpcap

watch sql base libpcap

我们经常的在 MySQL 里不停的执行show processlist想了解最近执行的 sql 语句状况,可常常拿不到我们想要的结果。

mysqlpcap 是一个基于 pcap 用于观察 sql 语句执行情况的工具。它能够了解到经过某个 MySQL 实例的 sql 语句以及 sql 影响的行数,还有 sql 的响应时间。

新增功能,目前已经支持 prepare statement。

compile

make

use

sudo ./mysqlpcap

use

只抓取某个用户的sql,逗号分割

sudo ./mysqlpcap -u root,user1

过滤某些用户的sql,逗号分割

sudo ./mysqlpcap -n user1,user2

针对某个ip的sql的抓取

sudo ./mysqlpcap -l 1.1.1.1

针对某个port的sql抓取

sudo ./mysqlpcap -p 3001

output format

timestamp           sql                                     latency(us)     rows            
---------           ---                                     -----------     ---             
9:22:33:815114      select 1                                291             1               
9:22:39:167115      select * from d limit 20000             229             -2              
9:22:39:167115      select * from d limit 20000             571             -2              
9:22:39:167115      select * from d limit 20000             707             -2              
9:22:39:167115      select * from d limit 20000             3508            -2              
9:22:39:167115      select * from d limit 20000             3628            -2              
9:22:39:167115      select * from d limit 20000             3675            20000           
9:22:45:227112      desc d                                  47891           3               
9:22:54:678621      insert into d values(1,2,3), (3,4,5)    33719           2    
  1. timestamp MySQL服务器接收到 sql 的时间。

  2. sql

  3. latency(us) 响应时间,MySQL服务器返回结果集的时间与timestamp的差值。由于结果集可能分多个tcp packet发送过来。 所以存在多条记录。

  4. 对于select语句则是结果集的行数,对于其它则是影响的行数。结果集超过一个tcp packet的大小,则行数显示在最后一个tcp packet对应的记录上。 上面的例子,select * from d limit 20000 返回的结果集由 6 个tcp packet组成,所以有 6 行记录,前5行的 rows 为 -2 ,最后一行的 20000 才是真是的返回行数。 latency显示的每个tcp packet 的响应时间。

  5. 第五列是用户

  6. 如果是 prepare statement 则值会显示在 sql 的后面,用方括号包围住。

prepare statement 的支持

use

sql 在前面,方括号里为具体的值。

TODO

  • keyword filter
  • output threading
  • pf_ring
  • multi stmt
  • support shrink hash entry(free session->sql && session->size)

changelog

  • user
  • latency
  • rows
  • sql
  • log
  • prepare
  • multi session big resultset
  • support bond netcard, fix libpcap bug
  • support show src ip (-z)
  • support drop packet and chao order packet
  • ignore remote MySQL port connect me random port, data, for example: replication,
  • ignore me connect rmeote MySQL data
  • support specify detail ip (-l)
  • support bond card repeat packet(same seq)
  • support user level sql capture, now can use parameter -u -n
  • support use signal SIGUSR1 inquire drop percentage
  • support reload machine address
  • support delete idle connection

version

0.01

tcpcollect's People

Contributors

bryant1410 avatar hoterran 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  avatar  avatar  avatar  avatar  avatar

tcpcollect's Issues

multistatement protocol

T 127.0.0.1:50724 -> 127.0.0.1:3306 [AP]
  19 00 00 00 03 73 65 6c    65 63 74 20 31 3b 73 65    .....select 1;se
  6c 65 63 74 20 2a 20 66    72 6f 6d 20 6e             lect * from n

T 127.0.0.1:3306 -> 127.0.0.1:50724 [AP]
  01 00 00 01 01 17 00 00    02 03 64 65 66 00 00 00    ..........def...
  01 31 00 0c 3f 00 01 00    00 00 08 81 00 00 00 00    .1..?...........
  05 00 00 03 fe 00 00 0a    00 02 00 00 04 01 31 05    ..............1.
  00 00 05 fe 00 00 0a 00                               ........

T 127.0.0.1:3306 -> 127.0.0.1:50724 [AP]
  01 00 00 06 01 1e 00 00    07 03 64 65 66 04 74 65    ..........def.te
  73 74 01 6e 01 6e 01 6e    01 6e 0c 3f 00 0b 00 00    st.n.n.n.n.?....
  00 03 00 00 00 00 00 05    00 00 08 fe 00 00 22 00    ..............".
  02 00 00 09 01 31 02 00    00 0a 01 32 02 00 00 0b    .....1.....2....
  01 32 02 00 00 0c 01 31    02 00 00 0d 01 31 02 00    .2.....1.....1..
  00 0e 01 31 02 00 00 0f    01 31 02 00 00 10 01 31    ...1.....1.....1
  02 00 00 11 01 31 02 00    00 12 01 31 02 00 00 13    .....1.....1....
  01 31 02 00 00 14 01 31    02 00 00 15 01 31 02 00    .1.....1.....1..
  00 16 01 31 05 00 00 17    fe 00 00 22 00             ...1.......".

COM_STMT_SEND_LONG_DATA

Mysql_stmt_send_long_data function can send one column data before mysql_stmt_execute. Normally, if column type is blob, we will try it's.

对 secure-auth 的支持

对于一些老版本的 MySQL 存在以下情况

/*
This happens when client (new) sends password scrambled with
scramble(), but database holds old value (scrambled with
scramble_323()). Here we please client to send scrambled_password
in old format.
*/

于是服务端接受到 auth packet 返回的不是 ok,error 包,而是 eof 包(send_old_password_request 函数发送的是eof packet)

sql_connect.cc
=================
 372     if (send_old_password_request(thd) ||
 373         my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) 

而客户端发上来的是通过 scramble_323 加密过的密码。

sql/client.c
================
2411   if (pkt_length == 1 && net->read_pos[0] == 254 &&
2412       mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2413   {                                                                                                                      
2414     /*
2415       By sending this very specific reply server asks us to send scrambled
2416       password in old format.      
2417     */                             
2418     scramble_323(buff, mysql->scramble, passwd);
2419     if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
2420         net_flush(net))            
2421     {
2422       set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2423                                ER(CR_SERVER_LOST_EXTENDED),
2424                                "sending password information",
2425                                errno);
2426       goto error;                  
2427     }
2428     /* Read what server thinks about out new auth message report */
2429     if (cli_safe_read(mysql) == packet_error)
2430     {
2431       if (mysql->net.last_errno == CR_SERVER_LOST)
2432         set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2433                                  ER(CR_SERVER_LOST_EXTENDED),
2434                                  "reading final connect information",
2435                                  errno);
2436       goto error;
2437     }
2438   }

pcap_set_buffer_size 设置缓冲区无效的bug

在看 libpcap 代码的时候发现了这个问题。

目前的代码是 pcap_open_live 然后再 pcap_set_buffer_size,其实内存已经在pcap_open_live 的时候就划分好了,所以在此之后的 pcap_set_buffer_size 仅仅就是修改了一个值没有做任何事情。

新方法:
pcap_create
pcap_set_snaplen
pcap_set_timeout
pcap_set_buffer_size
pcap_activate (这里划分 内存)

对于 bond 网卡的机器,重复包问题的解决。

对于 bond 网卡,包会重复发两份,两个 seq 一致,但重复的数据严重影响了程序内部状态机。

对于出包,现在的解决的方法是,当期待 seq 大于 接受 seq 的就认为是重复包,抛弃之。

Why not use libmysqlclient-dev ?

I see that some interface of mysql has been moved to your project, i think it's better to use the library of mysql client.
BTW, the log file open and close each time it writes information, it's not necessary.

replicator 用户的 hash slot 未能删除的bug

在测试环境的日志里发现大量的 replicator 用户的 hash slot 被删除的信息,这意味着 replicator 用户没有即时的清理,

由于replicator 的连接非常的频繁(虽然线上会取消 replicator 用户的数据)但是还是要即时清理这些slot.

对于 replicator 用户的业务是这样的.

             master                  slave
              <----socket          新的连接
             handshake --->
             <-----auth
             ok ----->
             <------sql1
             result ---->
             ....
             ....
             <------COM_BINLOG_DUMP
            result ------>
            eof --------->     上次连接
           <----------rst
           <-----------rst

代码在服务端 发送 eof 关闭上次的这个连接.

test_bug9159 会带来bug

源头是 stmt 执行一半, sql 执行一次, tcp_seq 没设置正确导致的bug.

下一个版本,两个 tcp_seq 会修复这个问题.

Segmentation fault.

(gdb) bt
#0 0x000000334a47843b in strnlen () from /lib64/libc.so.6
#1 0x000000334a44655e in vfprintf () from /lib64/libc.so.6
#2 0x000000334a44d00a in printf () from /lib64/libc.so.6
#3 0x0000000000403f50 in process_ip (mp=0x1a293010, ip=0x2b3aa453b050, tv=

  {tv_sec = 1344932314, tv_usec = 465681}) at process-packet.c:239

#4 0x0000000000403b7d in process_packet (user=0x1a293010 "?])\032", header=0x7fff065fad20,

packet=0x2b3aa453b040 "") at process-packet.c:151

#5 0x000000000041a69a in pcap_read_linux_mmap ()
#6 0x0000000000405588 in pcap_loop ()
#7 0x0000000000403a6f in start_packet (mp=0x1a293010) at process-packet.c:99
#8 0x0000000000402a14 in main (argc=1, argv=0x7fff065fb188) at mysqlpcap.c:263

kernel:
Linux 2.6.18-92.1.18.el5 #1 SMP Wed Nov 12 09:19:49 EST 2008 x86_64 x86_64 x86_64 GNU/Linux

dist:
Centos 5.2

null显示

抓到的日志,显示 数据库,和账号都是 null 是什么意思。谢谢

COM_FIELD_LIST protocol

T 127.0.0.1:59214 -> 127.0.0.1:3306 [AP]
04 00 00 00 04 61 31 00 .....a1.

T 127.0.0.1:3306 -> 127.0.0.1:59214 [AP]
23 00 00 01 03 64 65 66 04 74 65 73 74 02 61 31 #....def.test.a1
02 61 31 02 63 31 02 63 31 0c 3f 00 0b 00 00 00 .a1.c1.c1.?.....
03 00 00 00 00 00 fb 05 00 00 02 fe 00 00 02 00 ................

take care, this packet without header packet, field packet is first

pcap/sll.h No such file

小小小小磊磊磊:回复@hoterran-阮若夷:centos6.0没问题,但是centos5.4有问题gcc -g -Wall -c -o process-packet.o process-packet.c process-packet.c:33:22: error: pcap/sll.h: No such file or directory (33分钟前)

big com_stmt_execute bug

[19612][L_OK] 03-18 17:36:04 - datalen:977 seq:3536215663 dport:3306 sport:38352 incoming:1 packet:

0 0 0 0 0 0 1 0 0 0 5 62 75 79 65 72 0 0 0 0 0 0 0 0 0 0 0 0 b dd 7 3 12 11 1e 14 0 0 0 0

[19612][L_ERR] 03-18 17:36:04 - Assertion failed: session->next->ps == '0', hash.c, line 649
[19612][L_OK] 03-18 17:36:04 - datalen:977 seq:3536215663 dport:3306 sport:38352 incoming:1 packet:

0 0 0 0 0 0 1 0 0 0 5 62 75 79 65 72 0 0 0 0 0 0 0 0 0 0 0 0 b dd 7 3 12 11 1e 14 0 0 0 0

[19612][L_OK] 03-18 17:36:04 - datalen:1448 seq:3536214215 dport:3306 sport:38352 incoming:1 packet:

80 a7 e6 b8 a9 e8 89 af ef bc 8c e7 bb bf e8 89 b2 e5 a4 a9 e7 84 b6 ef bc 8c e7 ba af e6 89 8b e5 b7 a5 e7 bc 96 e5 88

[19612][L_OK] 03-18 17:36:04 - datalen:7240 seq:3536206975 dport:3306 sport:38352 incoming:1 packet:

64 74 68 3d 22 32 22 3e 3c 2f 74 64 3e 3c 74 64 20 77 69 64 74 68 3d 22 31 34 22 3e 3c 2f 74 64 3e 3c 74 64 20 77 69 64

[19612][L_OK] 03-18 17:36:04 - datalen:1448 seq:3536205527 dport:3306 sport:38352 incoming:1 packet:

65 2b 0 0 17 c1 2e 0 0 0 1 0 0 0 20 0 0 0 0 9b 59 bd 5 1 fd 0 fd 0 fd 0 fd 0 fd 0 6 0 8 0 fd 0

对于协议 compress 的支持

某些用户会在连接的时候开启 compress 的功能,这就导致接下来的 sql 和结果集 不再显示的可以抓取,对于这种用户,直接过滤所有接下来的交互。

在处理乱包的一个错误。

一个很大的 sql ,返回的结果集超大。

[16252][L_DEBUG] 12-27 02:29:46 - is_in:0-datalen:4344-tcp:2277484271 [58024]-[3306]
[16252][L_DEBUG] 12-27 02:29:46 - is_in:0-datalen:4344-tcp:2277484271 [58024]-[3306]
[16252][L_DEBUG] 12-27 02:29:46 - bond repeat packet
[16252][L_DEBUG] 12-27 02:29:46 - is_in:0-datalen:4344-tcp:2277492959 [58024]-[3306]
[16252][L_ERR] 12-27 02:29:46 - error packet expect 2277488615 but 2277492959 drops:14506

需要的 2277488615 没到,此时会已经解析的结果集给clear掉。这造成了一个大问题。

过上一个 来了,结果集已经被清理了,于是造成了

[16252][L_DEBUG] 12-27 02:29:46 - is_in:0-datalen:1448-tcp:2277488615 [58024]-[3306]
[16252][L_DEBUG] 12-27 02:29:46 - 1448

parse_result 以为是新的记录的错误。

对于超 大 型 sql 的bug

目前 inbound 函数并没有通过状态机,根据当前状态来引导接下来的动作,仅仅是根据 data 里的内容,这是不对的。

对于 超大的 sql (超过一个以太包)在首部来到的时候,packet.c(367) 并没把sql 存入到状态机里。
接下来的 sql 在 inbound 函数之时,又会一定几率导致 packet.c(278) 的 断言 ASSERT(cmd >= 0) 的失败,同样is_sql函数的调用也失去了作用,所以这块需要重构。

未来 inbound, outbound 函数 第一步就是 hash_get 拿到状态机的信息,再接合 data 来进行动作。

空闲连接的回收机制

目前不接受fin包,仅仅接受 COM_QUIT。所以对于异常退出的连接,或者一直处于 idle 状态的连接没有清理工作。

于是现在添加了对hash表的扫描工作,清理时间太长的连接。

prepare ok resultset big packet bug

prepare ok 的结果集过大的包.

这里有两个问题,一个是 bond repeat 还是会经过这个函数,这个是设计上的问题,
下次要添加 in_seq, out_seq 才能解决这个问题.

第二 resultset过大,tail packet 也会经过这个函数,解决方法是 判读是否是头包,尾包直接跳过.

临时方案.

快速短连接造成的问题。

proxy 与 MySQL 之间的连接,很多是短连接,创建关闭特别快速,出现了很多状态为 2,然后出现 auth packet 的情况。

filterUser 用户 slot 没有及时删除

filter user 也会进入 slot,目的是为了翻辩接下来通过 status 过滤不需要的packet.

但这带来了问题,这些用户的关闭包也没有处理.

设计,在发现是 filter 用户的时候,允许 COM_QUIT 的包进入.

增加一个辅助线程

增加辅助线程的主要目的是,后台获取 ip 地址,这个如果主线程来做太容易造成大量丢包.

带到主线程 来拿新地址的时候,仅仅需要切换一下两个指针即可.

释放地址全交给辅助线程来完成.

对于大的sql,存在重复包乱包的情况

由于包是二层的,所以丢包乱包再所难免。尤其糟糕的网络环境。

15:03:42.854429 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], seq 49730:51178, ack 56528, win 1002, options [nop,nop,TS val 4388018 ecr 337056858], length 1448
15:03:42.854463 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], seq 51178:52626, ack 56528, win 1002, options [nop,nop,TS val 4388018 ecr 337056858], length 1448
15:03:42.854470 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [P.], seq 52626:52930, ack 56528, win 1002, options [nop,nop,TS val 4388018 ecr 337056858], length 304
15:03:42.893687 IP 10.202.65.238.mysql > 10.1.170.132.60308: Flags [.], ack 51178, win 126, options [nop,nop,TS val 337837350 ecr 4388018], length 0
15:03:43.106006 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], seq 51178:52626, ack 56528, win 1002, options [nop,nop,TS val 4388081 ecr 337837350], length 1448
15:03:43.106102 IP 10.202.65.238.mysql > 10.1.170.132.60308: Flags [.], ack 52626, win 126, options [nop,nop,TS val 337837562 ecr 4388081], length 0
15:03:43.107202 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [P.], seq 52626:52930, ack 56528, win 1002, options [nop,nop,TS val 4388081 ecr 337837562], length 304
15:03:43.107291 IP 10.202.65.238.mysql > 10.1.170.132.60308: Flags [.], ack 52930, win 126, options [nop,nop,TS val 337837563 ecr 4388081], length 0
15:03:43.107389 IP 10.202.65.238.mysql > 10.1.170.132.60308: Flags [.], seq 56528:59424, ack 52930, win 126, options [nop,nop,TS val 337837563 ecr 4388081], length 2896
15:03:43.107398 IP 10.202.65.238.mysql > 10.1.170.132.60308: Flags [P.], seq 59424:60027, ack 52930, win 126, options [nop,nop,TS val 337837563 ecr 4388081], length 603
15:03:43.108621 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], ack 57976, win 1002, options [nop,nop,TS val 4388081 ecr 337837563], length 0
15:03:43.108811 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], ack 59424, win 1002, options [nop,nop,TS val 4388081 ecr 337837563], length 0
15:03:43.108825 IP 10.1.170.132.60308 > 10.202.65.238.mysql: Flags [.], ack 60027, win 993, options [nop,nop,TS val 4388081 ecr 337837563], length 0

libpcap 的一处修改和 fakeNow导致断言的问题.

  1. 发现一个奇怪的现象,poll 里返回数据,然后 pcap_get_ring_frame 确没拿到数据,通过pcap_stat 看到没有丢包.于是 pcap_dispatch 返回了 0 ,但并不是超时导致的.

我的目的,出现超时 3s,则 fakeNow 需要time里取,否则使用协议栈头的时间绰.

用压力程序一压,发现大量的 返回 0 ,但非超时,此时大量的调用了time,这比较消耗性能.

如果 fakeNow 不通过 time更新时间,则会有很多数据cache住,两难.

所以修改了 pcap_read_linux_mmap 一旦 poll timeout 了,直接返回 -10 ,这样 外面的程序就知道是否是真的超时了, 没有其他好方法了.

  1. time(NULL) 赋值的时候需要注意,这个 time 出来的值有可能比协议栈里的时间还早,这点很奇怪,导致了几处断言的错误.
    所以fakeNow的赋值,就算是 time,也要注意比较大小

一个连接,两个 stmt_id 的支持

目前如果一个连接,两个stmt语句的话,输出是有错的,因为stmt_id 仅留了一个字段。
这个需要一个链表来保存stmt和sql还有param

如何应对 pcap 丢包现象。

由于使用 pcap 处于三层,所以存在丢包和乱包的可能性,因此程序在处理每个包的时候都有考虑是否是连续包通过判断 tcp->seq 和 包的长度来达到。

对于乱序和丢包现在的处理方案是输出会报出 error packet。

tcpcollect client 模式

hi @hoterran,

tcpcollect 如果可以跑在客户端,从客户端来查看数据包交换的情况,我们在排查问题,有时会用到。 如果提 pr 到这里,不知道会不会考虑 merge.

最后感谢大神写出这么好用的工具~

针对某个用户的sql输出。

我就关心某个用户的sql,我们可以 -u root
或者我不关心某个用户的,我们可以 -n replicator, aurora

用户名用逗号分割

COM_PROCESSINFO and COM_USER

T 127.0.0.1:47033 -> 127.0.0.1:3306 [AP]
  01 00 00 00 0a                                        .....       

T 127.0.0.1:47033 -> 127.0.0.1:3306 [AP]
  21 00 00 00 11 6b 6b 6b    00 14 d9 8d 8f ef 1e 51    !....kkk.......Q
  b8 06 6f d3 81 17 bc 8a    7b 00 dc 6a af 5a 74 65    ..o.....{..j.Zte
  73 74 00 08 00      

Prepare(Mysql C API)

I use 'prepare '(mysql c api) to insert/update/delete the sql, but the sql column of the result from tcpcollect contain garbled character.

把 pcap_loop 改成 pcap_dispatch

除了收包之外,我们平时还要定时处理一些东西(比如日志输出,清理多余内存)。

如果设置 to_ms = 0 则包来了,才能从poll 里退出。所以我们必须设置 to_ms > 0 。

对于 to_ms > 0 的超时,pcap_loop 并不会执行回调,所以我们只能使用 pcap_dispatch 这样更加方便。

非超时在回调里处理,超时在 pcap_dispatch 后面处理。

压缩协议的一些说明

客户端激活压缩

mysql -h 127.0.0.1 -u root -proot --compress=true

压缩协议由两部分组成,header 和 payload

  1. compress packet header

    3 length of compress payload
    1 compress sequence id
    3 length of payload before compression`

  2. compress packet payload

payload 有分 查询语句 和 结果集

查询语句的压缩

对于查询语句 payload 低于 50 的,会采用 uncompress payload,就是说对内容不压缩保持原貌。

下面是一个 select 1 的例子

T 127.0.0.1:44653 -> 127.0.0.1:3306 [AP]
  0d 00 00 00 00 00 00 09    00 00 00 03 73 65 6c 65    ............sele
  63 74 20 31                                           ct 1  

下面是一个查询语句 payload超过 50 的,compress payload

select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';

T 127.0.0.1:50822 -> 127.0.0.1:3306 [AP]
  19 00 00 00 33 00 00 78    9c d3 67 60 60 60 2e 4e    ....3..x..g```.N
  cd 49 4d 2e 51 50 4f 24    06 a8 03 00 9a 6c 11 26    .IM.QPO$.....l.&

返回的结果集,都是 compress payload(ok,error,eof 不压缩,仅有 resultset 可能压缩)

正常的结果集,是分多个packet,

T 127.0.0.1:41085 -> 127.0.0.1:3306 [AP]
  09 00 00 00 03 73 65 6c    65 63 74 20 31             .....select 1   

T 127.0.0.1:3306 -> 127.0.0.1:41085 [AP]
  01 00 00 01 01 17 00 00    02 03 64 65 66 00 00 00    ..........def...
  01 31 00 0c 3f 00 01 00    00 00 08 81 00 00 00 00    .1..?...........
  05 00 00 03 fe 00 00 02    00 02 00 00 04 01 31 05    ..............1.
  00 00 05 fe 00 00 02 00                               ........        

而 compress payload,会合并多包。

T 127.0.0.1:41087 -> 127.0.0.1:3306 [AP]
  0d 00 00 00 00 00 00 09    00 00 00 03 73 65 6c 65    ............sele
  63 74 20 31                                           ct 1            

T 127.0.0.1:3306 -> 127.0.0.1:41087 [AP]
  35 00 00 01 38 00 00 78    9c 63 64 60 60 64 14 67    5...8..x.cd``d.g
  60 60 62 4e 49 4d 63 00    72 0c 19 78 ec 19 18 81    ``bNIMc.r..x....
  2c 8e 46 20 c1 c0 ca c0    c0 fc 0f 28 0d 84 0c 2c    ,.F .......(...,
  8c 86 40 2e 2b 98 0b 00    79 bb 04 a0                ..@.+...y...    

总结

假设没压缩前,paylaod = N 字节,那么整个 packet 为 N + 4 字节。

N + 4 个字节进行一个压缩成 M 字节,那么整个 compress packet 为 3 + 1 + 3 + M 个字节。

结果集中 field number 过大的bug

之前的处理环节都仅仅针对 resultset 分包的处理,其实某些大的查询 field_number 也会分包,甚至在 eof 包的时候也可能出现分包。

线上就看到一个这样的 sql 超级大, field 环节就分了两个包。所以parse_result 需要调整。

select this_.agent_id as agent1_41_0_, this_.creator as creator41_0_, this_.gmt_create as gmt3_41_0_, this_.gmt_modified as gmt4_41_0_, this_.is_deleted as is5_41_0_, this_.modifier as modifier41_0_,this_.agentgroup_id as agentgroup7_41_0_, this_.former_monitor_id as former8_41_0_, this_.former_super_agent_id as former9_41_0_, this_.host_id as host10_41_0_, this_.host_name as host11_41_0_, this_.host_state as host12_41_0_, this_.ip as ip41_0_, this_.is_apply as is14_41_0_, this_.is_connected as is15_41_0_, this_.is_repair as is16_41_0_, this_.is_super as is17_41_0_, this_.is_transfered as is18_41_0_, this_.monitor_db_id as monitor19_41_0_, this_.monitor_id as monitor20_41_0_, this_.node_id as node21_41_0_, this_.ob_ip as ob22_41_0_, this_.site_id as site23_41_0_, this_.site_rack as site24_41_0_, this_.site_room as site25_41_0_, this_.site_row as site26_41_0_, this_.site_shelf as site27_41_0_, this_.subnet as subnet41_0_, this_.super_agent_id as super29_41_0_, this_.type as type41_0_, this_.version as version41_0_ from agent this_ where this_.ip='10.249.241.129' and this_.is_deleted=0 limit 1;

对于多个会话同时有超大型结果集,返回行数不对。

当resultset超过一个tcp packet之后,那么就需要有地方保存这个resultset里的行数和余下的数据。
以前这个是放在mysql-protocl.c的静态变量里。

当有多个会话同时有超大结果集的时候,肯定会报错,于是把变量存在session变量里了。

几个bug的修复

  1. hash.c 存在的内存泄漏,要把sql复制给session->next->sql 实际sql指向了同一块内存。
  2. packet.c COM_EXECUTE 的格式和 compress payload 很类似,做了区分
    tcp_seq 的调整。

load data local file protocol

[root@alsdb_admin1a ~]# cat /root/ss.csv 
1,2
3,4

load data local infile '/root/ss.csv' into table test  fields terminated by ',' (@id,@name) set id=@id, name=@name;


T 172.18.111.21:58118 -> 42.120.126.31:3306 [AP]
  73 00 00 00 03 6c 6f 61    64 20 64 61 74 61 20 6c    s....load data l
  6f 63 61 6c 20 69 6e 66    69 6c 65 20 27 2f 72 6f    ocal infile '/ro
  6f 74 2f 73 73 2e 63 73    76 27 20 69 6e 74 6f 20    ot/ss.csv' into 
  74 61 62 6c 65 20 74 65    73 74 20 20 66 69 65 6c    table test  fiel
  64 73 20 74 65 72 6d 69    6e 61 74 65 64 20 62 79    ds terminated by
  20 27 2c 27 20 28 40 69    64 2c 40 6e 61 6d 65 29     ',' (@id,@name)
  20 73 65 74 20 69 64 3d    40 69 64 2c 20 6e 61 6d     set id=@id, nam
  65 3d 40 6e 61 6d 65                                  e=@name         

T 42.120.126.31:3306 -> 172.18.111.21:58118 [AP]
  0d 00 00 01 fb 2f 72 6f    6f 74 2f 73 73 2e 63 73    ...../root/ss.cs
  76                                                    v               

T 172.18.111.21:58118 -> 42.120.126.31:3306 [AP]
  08 00 00 02 31 2c 32 0a    33 2c 34 0a 00 00 00 03    ....1,2.3,4.....

T 42.120.126.31:3306 -> 172.18.111.21:58118 [AP]
  37 00 00 04 00 02 00 02    00 00 00 2f 52 65 63 6f    7........../Reco
  72 64 73 3a 20 32 20 20    44 65 6c 65 74 65 64 3a    rds: 2  Deleted:
  20 30 20 20 53 6b 69 70    70 65 64 3a 20 30 20 20     0  Skipped: 0  
  57 61 72 6e 69 6e 67 73    3a 20 30                   Warnings: 0   

prepare statement

hi,hoterran

我测试下来,发现为什么prepare statement 的sql 执行 好像没有抓到。

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.