MySQL 比如一个update T SET age = 9 WHERE id=1;语句执行后,这个时候更新内存中的数据,磁盘仍为旧数据吧,然后马上select查询id=1的age依然可以查到最新的值。请问这个原理是什么?
答案可能是:innodb_flush_log_at_trx_commit参数设置吧!
innodb_flush_log_at_trx_commit值为1 : 提交事务的时候,就必须把 redo log 从内存刷入到磁盘文件里去,只要事务提交成功,那么 redo log 就必然在磁盘里了。注意,因为操作系统的“延迟写”特性,此时的刷入只是写到了操作系统的缓冲区中,因此执行同步操作才能保证一定持久化到了硬盘中。
个人理解:
假设update T SET age = 9 WHERE id=1;这是一个完整事务,执行完后,其内存已经更新,同时完成了bin log和redo log刷盘。
再次执行查询语句时,此时内存中已有该数据的页,所以直接从内存中读取并返回。根本不会去磁盘去查,或者去根据各种日志进行计算。
至于数据刷盘,应该就是后台进行的。
再补充一下:
如果执行update T SET age = 9 WHERE id=1;时,此时数据页没有在内存中,如果id是普通索引,这时会将改动记录到change buffer中,记日志,然后就直接返回了。
下次select时,会将数据页读入内存,然后再结合change buffer的操作,获取最新值返回。
这些过程可能磁盘上一直是旧数据,但不影响读取的正确性。