浅析MyISAM插入数据过程

环境:mysql 5.7.28 

获取连接id

mysql> show processlist;  

+----+------+-----------+------+---------+------+----------+------------------+  
| Id | User | Host | db | Command | Time | State | Info |  
+----+------+-----------+------+---------+------+----------+------------------+  
| 2 | root | localhost | NULL | Query | 0 | starting | show processlist |  
+----+------+-----------+------+---------+------+----------+------------------+

获取到连接id是2

根据连接id获取线程id

mysql> select THREAD_ID, thd_id, conn_id, THREAD_OS_ID, name  from performance_schema.threads t, sys.processlist p   where p.thd_id = t.thread_id and conn_id > 0;  
+-----------+--------+---------+--------------+--------------------------------+  
| THREAD_ID | thd_id | conn_id | THREAD_OS_ID | name |  
+-----------+--------+---------+--------------+--------------------------------+  
| 26        | 26      | 1      | 5599         | thread/sql/compress_gtid_table |  
| 27        | 27       | 2     | 6717         | thread/sql/one_connection |  
+-----------+--------+---------+--------------+--------------------------------+

获取到2号连接对应的线程id是6717

查看6717打开的所有文件描述符

ls -alh  /proc/6717/fd

屏幕快照 2019-12-27 下午6.29.28.png

客户端发送数据

insert into user2(name,age) values('a',10);

服务端strace抓到的数据

strace -T -tt  -s300   -p 6717
`18:07:59.673626 poll([{fd=4, events=POLLIN|POLLPRI}], 1, 28800000) = 1 ([{fd=4, revents=POLLIN}]) <6.400402>`

`18:08:06.074079 recvfrom(4,``"+\0\0\0"``, 4, MSG_DONTWAIT, NULL, NULL) = 4 <0.000142>`

`18:08:06.074319 gettimeofday({1577441286, 74342}, NULL) = 0 <0.000053>`

`18:08:06.074455 clock_gettime(CLOCK_REALTIME, {1577441286, 74472708}) = 0 <0.000052>`

`//1、读取到客户端数据`

`18:08:06.074547 recvfrom(4,``"\3insert into user2(name,age) values('a',10)"``, 43, MSG_DONTWAIT, NULL, NULL) = 43 <0.000047>`

`18:08:06.074673 gettimeofday({1577441286, 74688}, NULL) = 0 <0.000013>`

`18:08:06.074857 clock_gettime(CLOCK_REALTIME, {1577441286, 74875405}) = 0 <0.000011>`

`18:08:06.074938 clock_gettime(CLOCK_REALTIME, {1577441286, 74954987}) = 0 <0.000010>`

`18:08:06.075059 gettimeofday({1577441286, 75076}, NULL) = 0 <0.000011>`

`//2、写真实数据  51 -> /var/lib/mysql/test/user2.MYD`

`18:08:06.118474 pwrite64(51,``"\3\0\20\0\0\374\2\33\267\0\0\0\0\0\1a\n\0\0\0"``, 20, 480000020) = 20 <0.015135>`

`//3、写binlog数据  20 -> /var/lib/mysql/mysql-bin.000001`

`18:08:06.134313 write(20,``"\6\330\5^\"\1\0\0\0A\0\0\0\333\0\0\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0CJ\7#\6\330\5^\2\1\0\0\0O\0\0\0*\1\0\0\10\0\2\0\0\0\0\0\0\0\4\0\0!\0\0\0\0\0\0\1 \0\240U\0\0\0\0\6\3std\4!\0!\0\10\0\f\1test\0test\0BEGIN\"d\205\337\6\330\5^\5\1\0\0\0 \0\0\0J\1\0\0\0\0\2\2\33\267\0\0\0\0\0n\310&'\6\330\5^\2\1\0\0\0t\0\0\0\276\1\0\0\0\0\2\0\0\0\0\0\0\0\4\0\0!\0\0\0\0\0\0\1 \0\240U\0\0\0\0\6\3std\4!\0!\0\10\0\f\1test\0test\0insert into user2(name,age) values('a',10)\232\306K\330\6\330\5^\2\1\0\0"``..., 372) = 372 <0.000048>`

`//4、刷盘binlog数据`

`18:08:06.134413 fdatasync(20)           = 0 <0.007731>`

`//5、写索引数据    50 -> /var/lib/mysql/test/user2.MYI`

`18:08:06.134414 pwrite64(50,``"\0\2\1"``, 3, 24) = 3 <0.000075>`

`...`

`18:08:06.142744 gettimeofday({1577441286, 142789}, NULL) = 0 <0.000040>`

`//6、给客户端返回结果`

`18:08:06.142851 sendto(4,``"\n\0\0\1\0\1\375\2\33\267\2\0\0\0"``, 14, MSG_DONTWAIT, NULL, 0) = 14 <0.000232>`

`18:08:06.143147 clock_gettime(CLOCK_REALTIME, {1577441286, 143180187}) = 0 <0.000039>`

`18:08:06.143247 gettimeofday({1577441286, 143287}, NULL) = 0 <0.000036>`

`18:08:06.143352 gettimeofday({1577441286, 143395}, NULL) = 0 <0.000038>`

`18:08:06.143438 recvfrom(4, 0x35b61f0, 4, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable) <0.000026>`

`//7、等待客户端写入数据   POLLIN  普通或优先级带数据可读  POLLPRI 高优先级数据可读`

`18:08:06.143509 poll([{fd=4, events=POLLIN|POLLPRI}], 1, 28800000`

总结:

MyISAM 引擎在一个线程里完成了数据的写入,主要流程:

1、读取到客户端数据

2、写真实数据

3、写binlog数据[如果没开启binlog没有这一步]

4、刷盘binlog数据

5、写索引数据(没有建索引也会写索引数据,不知道是不是会像innodb一样会默认加主键索引

6、给客户端返回结果

欢迎大家斧正和补充。

你可能感兴趣的:(mysql,myisam)