环境: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
客户端发送数据
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、给客户端返回结果
欢迎大家斧正和补充。