MySQL更新一条数据之后查询到最新值原理是什么?

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 就必然在磁盘里了。注意,因为操作系统的“延迟写”特性,此时的刷入只是写到了操作系统的缓冲区中,因此执行同步操作才能保证一定持久化到了硬盘中。

阅读 7.6k
5 个回答

个人理解:
假设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的操作,获取最新值返回。
这些过程可能磁盘上一直是旧数据,但不影响读取的正确性。

肯定得同步啊, 磁盘是最简单的, 比较麻烦的是副本集, 进入写操作时, 主节点写入先执行, 然后通知所有副本集, 副本集确认之后, 才算真正插入成功. 当然也可以设置不需要副本集确认, 这样就有可能副本集读的节点还不能读取信息.

mysql在更新数据
-> 更新成功则删除缓存
mysql查询数据
-> 先查看缓存,此时缓存中没有,就去磁盘拿数据(新值),然后再刷到缓存。

在你修改这条数据之后,其实数据是没有立即到磁盘的,首先在内存里这个数据所在页会被加载,然后修改内存里的数据,并用append写到redo log(磁盘append写速度非常快,但是随机写慢),而这个脏页(被修改过的)会被刷到磁盘去的(时机不一定,有多个时机,一方面有线程负责刷脏页的,一方面当页被剔除出缓存页表的时候也会要把脏页刷到磁盘),而你查询能查到没有写到磁盘的数据是因为这个数据本来就已经在缓存页里了不需要去磁盘加载了,直接返回了,数据到磁盘是一个异步的过程,详细的可以去看mysql原理的书里有些mysql是怎么工作的。主从库的话是需要从库监听了binlog的修改然后同步到自己这边内存执行,再落磁盘的,也是异步的,落磁盘时机是没法保证的。

用户不需要考虑什么内存, 磁盘. 这是由mysql服务器负责的.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题