典型回答 这种绝对性的问题,答案肯定是不能的。
首先,MySQL有很多引擎,其中一部分是基于磁盘的,比如Innodb,Myisam等,但是也有基于内存的,比如Memory,而基于内存的这种如果断电了,可能就丢数据了。
那么,基于磁盘的就万无一失了么?其实也不是。
日志要写入磁盘要经过几个过程:
如果你看过下面这篇文章,你会知道,MySQL为了保证数据不丢,在事务写入的时候做了2阶段提交。
✅什么是事务的2阶段提交?
这里面画图的时候其实是考虑的默认情况的,啥意思呢,先来看2个MySQL的参数。
innodb_flush_log_at_trx_commit是MySQL InnoDB存储引擎独有的参数,用于控制InnoDB的Redo log日志记录方式。取值范围为0、1、2:
0:只写入LogBuffer,不会把Redo日志写入磁盘,而是靠InnoDB的后台线程每秒写入磁盘。 1(默认值):写入LogBuffer,并立即将LogBuffer数据写入磁盘缓冲区并刷盘。 2:写入LogBuffer,并立即将Redo日志写入操作系统的磁盘缓冲区,每秒由操作系统调度刷盘一次。 <font style="color:rgb(24, 24, 24);">sync_binlog</font>是MySQL Binlog日志的重要参数,用于控制Binlog的更新策略。取值范围 0、1 或 N(正整数):
0:事务提交后仅将Binlog写入文件系统缓存,依赖操作系统调度刷盘。 1(默认值):每次事务提交后立即将Binlog写入磁盘。 >1:每N个事务提交后,立即将Binlog写入磁盘。 那么也就是说,如果你了解操作系统的write和fsync指令的话,翻译一下就是这样的:
✅write和fsync的区别是什么?
**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">innodb_flush_log_at_trx_commit = 1</font>** **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">innodb_flush_log_at_trx_commit = 0</font>** **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">innodb_flush_log_at_trx_commit = 2</font>** 动作 写LogBuffer**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">write()</font>** 到 OS Cache**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">fsync()</font>** 到磁盘 写LogBuffer 写 Log Buffer** **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">write()</font>** 到 OS Cache** **<font style="color:rgb(24, 24, 24);">sync_binlog</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);"> = 1</font>** **<font style="color:rgb(24, 24, 24);">sync_binlog</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);"> = 0</font>** **<font style="color:rgb(24, 24, 24);">sync_binlog</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);"> > 1</font>** 动作 写LogBuffer**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">write()</font>** 到 OS Cache**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">fsync()</font>** 到磁盘 写LogBuffer 写LogBuffer每 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">N</font>** 个事务提交后,才将 binlog **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">write()</font>** 到 Page Cache 并执行 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">fsync()</font>** 到刷盘。 那么也就意味着,如果你想让数据不丢,至少要把<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">innodb_flush_log_at_trx_commit</font>和<font style="color:rgb(24, 24, 24);">sync_binlog</font>都设置为1,让他们立刻写入磁盘并刷盘。
...