Innodb从5.5开始使用linux的Native AIO(后面简称N-AIO),告别之前仿真的方式。我们下面从5.6.10的源码分析Innodb的Native AIO使用架构。
Innodb有N个io handler threads(N=1个ibuf_io_thread + 1个log_io_thread + innodb_read_io_threads个read_io_thread+ innodb_write_io_threads个write_io_thread),也是这些线程使用了N-AIO(及提交aio请求的线程)。首先我们看一下innodb的N-AIO核心数据结构及关系:
图1 N-AIO核心数据结构及关系
os_aio_array_t:表示某一类(ibuf,log,read,write)io handler所管理的innodb aio对象
mutex:该结构自身的mutex,下面我们会看到os_aio_array_t变量都是全局变量,并且对于read,write类型的os_aio_array_t可能会有多个线程并发访问(innodb_read_io_threads、innodb_write_io_threads),对于ibuf,log类型因为它们都只有一个线程,所以不存在并发访问问题
not_full:一个条件变量event,当这个os_aio_array_t的slot从full变成not full时它释放该条件变量,即there is space in the aioarray;显然该变量会在提交io的时候关心
is_empty:另一个条件变量event,当这个os_aio_array_t的slot从not empty变成empty的时候,会释放该条件变量,也即no pending aio in the aioarray;谁wait这个条件变量?
n_slots:该aio对象可容纳的pending aio event个数,也称为aio请求槽数,它等于该aio对象包括的所有线程(对于read,write类型则可能存在多个线程共处于该对象的管理内)可容纳的pending aio event个数,即=线程数 * 每个线程可支持的max pending aio event(256)
n_segments:该对象可处理的区间数,也是包括的线程数
cur_seg:当前区间号
n_reserved:已经被占用的pending aio event数
slots:n_slots个so_aio_slot_t(aio请求对象)的数组,也即n_segments 个线程共用n_slots个槽位来存放pending aio event
aio_ctx: n_segments个aio上下文的数组,即每个线程一个aio上下文
aio_event: n_slots个aio_event的数组,aio event完成后io_event保存的位置
os_aio_slot_t:一个innodb aio请求对象
is_read:bool,TRUE if a read operation
pos:该对象在os_aio_array_t->slots[]数组中的index
reserved: TRUE if this slot is reserved,被预留了或者叫被占用了
reservation_time:预定该slot的时间
len:io请求的长度
buf:io请求的buf
type:io operate type:OS_FILE_READ orOS_FILE_WRITE
offset:file offset in bytes
file:file where to read or write
name:file name or path
io_already_done:它的aio请求是否已经完成
message1:该aio操作的innodb文件描述符(f_node_t)
message2:额外的信息,这个信息也是在aio结束时每个处理函数使用的参数
control:该slot使用的aio请求控制块iocb,这也是该结构最重要的成员
n_bytes:bytes written/read
ret:AIO return code
f_node_t:innodb管理的在表空间或log space下的文件描述符(File node of a tablespaceor the log data space)
fil_space_t:上面的文件所属的空间(Tablespace or log data space)ÿ