wal日志的作用和产生过程
wal历史日志,记录数据库系统中的所有更改和操作,以确保没有任何数据由于故障而丢失,例如电源故障或其他导致服务器崩溃的服务器故障。
由于日志包含了关于已经执行的每个事务的足够信息,所以数据库服务器应该能够通过在事务日志中redo更改和操作来恢复数据库中的数据
wal的产生过程
数据操作都是在内存中完成的,将内存中的数据写入磁盘,叫数据的持久化(duration)。
一个数据的操作(包含INSERT ,UPDATE,DELETE),先在wal_buffer中写入wal日志,后将数据操作写入到data_buffer中, 然后数据写入日志后,这个操作就会返回成功,check point后,dirty page数据就会落入到数据PAGE实现持久化
这里如果在dirty_page还没写入磁盘前,数据库发生了宕机,数据库将会从最近的一个checkpoint开始应用wal日志里的操作,直到完成。wal也是有buffer的,如果buffer的内容未同步到磁盘,发生宕机的时,会丢失这一段在buffer内的事务。
流复制概述
备库不断的从主库同步相应的日志数据,并在备库apply每个WAL record,流复制每次传输是WAL日志的record,主库启动walsender进程,主要负责将主服务器产生的WAL日志记录发送给从库;
从库启动walreceiver进程,与对应的walsender进程通讯,负责接收主库发送的WAL日志记录;从库启动startup进程,负责将walreceiver进程接收到WAL日志记录在从库上replay,从而达成主从的数据同步
synchronous_commit=on(对应上图)
写操作,直到收到一个确认表明该提交在主服务器和从服务器上都已经被写入到磁盘上的预写式日志中
on强制将数据写入到磁盘
1 为on且没有开启同步备库的时候,会当wal日志真正刷新到磁盘永久存储后才会返回客户端事务已提交成功,
2 当为on且开启了同步备库的时候(设置了synchronous_standby_names),必须要等事务日志刷新到本地磁盘,并且还要等远程备库也提交到磁盘才能返回客户端已经提交.
remote_write
当事务提交时,不仅要把wal刷新到磁盘,还需要等wal日志发送到备库操作系统(但不用等备库刷新到磁盘),因此如果备库此时发生实例中断不会有数据丢失,
因为数据还在操作系统上,而如果操作系统故障,则此部分wal日志还没有来得及写入磁盘就会丢失,备库启动后还需要向主库索取wal日志。
local
当事务提交时,仅写入本地磁盘即可返回客户端事务提交成功,而不管是否有同步备库
off
写到缓存中就会向客户端返回提交成功,但也不是一直不刷到磁盘,延迟写入磁盘,
延迟的时间为最大3倍的wal_writer_delay参数的(默认200ms)的时间,所以如果即使关闭synchronous_commit,会造成最多600ms的事务丢失,此事务甚至包括已经提交的事务(会丢数据),但数据库确可以安全启动,不会发生块折断,只是丢失了部分数据,但对高并发的小事务系统来说,性能来说提升较大。
remote_apply
表示流复制主库提交事务时,需等待备库接收主库发送的wal流并写入wal文件,同时备库已经完成重做,之后才向客户端返回成功,简单的说remote_apply表示本地wal已落盘,备库wal已落盘并且已经完成重做,这个设置保证了拥有两份持久化的wal,同时备库也已经完成了重做。这个选项带来的事务响应时间最久