MySQL的binlog_row_image和PostgreSQL的full_page_writes
2021-03-11 10:36 abce 阅读(473) 评论(0) 编辑 收藏 举报MySQL的binlog_row_image
MySQL基于行的复制中,该变量决定了row images是如何被写入binary log的。在基于行的复制中,每一行的change事件包含两个镜像:一个“前镜像”,其列包含的是更新之前的内容;一个“后镜像”,其列包含更新之后的内容。通常,MySQL在前镜像和后镜像中记录整个行(即所有的列)。然而,在两个镜像中并不是必须严格地记录所有的行。如果只是记录实际需要的列,就可以节省磁盘,内存和网络的使用。
当删除一行记录,只会记录“前镜像”。当插入一行记录,只会记录“后镜像”。只有更新一行记录才会同时在binary log中记录“前镜像”和“后镜像”。
对于“前镜像”,只需要最少的列来唯一标识被记录的行。如果表包含主键,只要将主键列写入binary log。否则,如果表有一个唯一性非空索引,只需要记录该唯一性索引。如果表既没有主键,也没有唯一性非空索引,就需要在“前镜像”中记录所有的列。在“后镜像”中,只需要记录实际更改的列。
通过参数binlog_row_image可以控制mysql全部或最少记录行镜像。可以设置为以下三个取值:
·full:在“前镜像”和“后镜像”中记录所有的列。是默认取值
·minimal:只是记录最少需要的列
·noblob:记录所有的列(和full类似),但是不用来唯一标识一行记录或没有被修改的blob、text列除外
该变量不被NDB支持。也不支持statement格式的二进制行格式。
当取值为minimal或noblob时,delete、update操作在满足以下条件下可以正确的工作(主库和备份必须同时满足):
·所有的列以相同的顺序出现,使用相同的数据类型
·表必须有相同的主键定义
(换句话说,表必须相同,除了辅助索引)
在全局或会话级别设置该变量,不会引起隐式提交;即在事务执行过程中也可以修改该变量的值。
PostgreSQL的full_page_writes
full_page_writes
(boolean
)
设置为on后,PostgreSQL服务器在检查点之后对页面的第一次写入时将整个页面写到 WAL 里面。这是必须的,因为对一个page的写操作在操作系统发生奔溃的时候,可能只是完了部分写,导致磁盘上的页同时包含了老的数据和新的数据。通常存储在WAL中的行级更改数据不足以在崩溃后恢复期间完全恢复此类页面。存储完整的页镜像可确保页面可以正确还原,但是代价是增加了必须写入WAL的数据量。 (由于WAL重放始终从检查点开始,因此在检查点之后的每个页面的第一次更改期间执行此操作就足够了。因此,减少全页写入成本的一种方法是增加检查点间隔参数)
禁用此参数可加快正常操作的速度,但在系统故障后可能会导致不可恢复的数据损坏或静默数据损坏。风险与关闭fsync相似,尽管较小,但仅应根据针对该参数建议的相同情况将其关闭。
关闭该参数不会影响使用WAL归档进行基于时间点的恢复。
该参数只可以在文件postgresql.conf中或在postgresql命令行中进行设置。默认为on。
postgresql的full_page_writes特性和innodb中的double write原理类似,但实现稍有不同,innodb double write生效时,在写真正的数据页前,把数据页写到doublewrite buffer中,doublewrite buffer写完并刷新后才往真正的数据页写入数据。