PostgreSQL源码定制:在线global read only


基于某云上功能需求,最近实现了类似于MySQL global read only的功能。PG的read only功能,也不再需要通过重起PG实现来实现。直接可以online更改PG实例级别

global read only 和 global read write功能, 以达到快速实现主备切换的功能。大大缩短了主备切换时间,提高了PG的高可性。弥补了PG在这一功能上的不足。

此次通过源码定制更改实现的PG版本global read only有许多明显的优势:

1.在设置global read only时,新的查询不会被堵

新进来session,read only直接生效,不需要重起PG实例。并用在设置global read only时,不会堵住新会话。因此避免了连接拥堵现象。

2.正在跑的事务,分级别对待

a.如果是事务块,也就是用户发起的”BEGIN”语句,那么已经执行完毕的语句不受影响。对于此事务中后面执行的语句,会受read only约束,不能执行DML操作。本事务会被终止。

b.如果是正在跑的语句,比如说有一个大的insert或者update。那么此操作不会受影响,设置 global read only需要等待此操作完成后,才返回。

global read only操作会等待所有running 的DML操作完成,并且做完”Immediate Checkpoint”后,再返回响应。这样做的理由是为了确保数据库状态的一致性。

尤其是在主备切换的情况下,更为关键和重要。

3.中断处理

如果在设置 global read only时失败,那么会被回滚,会被重新置为read write状态。

下面展示下源码patch实现结果:

session 1:查看当前数据库read only状态,显示当前为”Read Write”状态,即PG实例级别可以读写。

session 2:起事务,事务中为两个insert语句。我们先执行一个insert语句,但是不提交事务。

表创建语句:

create table grl_test (id int);

begin;

insert into grl_test values(1);

session 1:尝试将PG实例设置为global read only。此时可以看到,不能设置为”Read Only“状态,设置”Read Only”操作没有返回。

原因为 session 2并没有提交。这个符合我们的设计初衷,就是read only设置成功返回时,数据库为一致状态,此后没有user 级别写事务。

session 2:尝试发起第二条insert语句。可以看到insert失败了。原因为session 1尝试设置为 global read only时,虽然操作没有返回,

但是新的任何DML操作以及新的事务已经被约束为read only状态。不允许新的写事务容易理解,但是为什么不允许之前已经发起的事务中,不能DML操作呢?

这样做的原因是:

我们不想让先于设置read only之前的事务块,无限制的跑下去。这会让设置global read only的操作一直进行下去。如果read only设置不成功,

直接影响到主备的快速切换。细心的同学可能会发现,这只限于事务块。的确如此,事务块与一般事务的区别,请见我另外一篇文章”PostgreSQL 事务模型介绍“。

因为一般事务,只在command级别,跑完就结束了。我们可以等待,一般用户也容易理解,如果我们强行终止此类操作,会对应用影响比较大。一般command

级别的事务总是非常快的结束,尤其在OLTP系统中,基本上都是简单的command级别事务。事务块一般逻辑比较复杂,有这一限制,也是为了数据一致性考虑,

失败了,顶多重新跑就行了。总体上来讲,这也是基于目前市面上OLTP类应用系统的现实需求而定制的。

insert into grl_test values(2);

session 1:此时我们再来看session 1时,设置global read only已经成功了。session 2因为第二个命令违背了read only,导致事务被终止了。因此,也就再没有

running transaction了。global read only设置完成后,checkpoint向前推。我们就可以以此checkpoint为准,进行主备一致性切换。

上面完全实现了在线更改PG实例read only状态。我们再将实例在线改回到read write。是不是非常方便呢?

------------------------------------华丽丽的分割线------------------------------------

CentOS 6.3环境下yum安装PostgreSQL 9.3

PostgreSQL缓存详述

Windows平台编译 PostgreSQL

Ubuntu下LAPP(Linux+Apache+PostgreSQL+PHP)环境的配置与安装

Ubuntu上的phppgAdmin安装及配置

CentOS平台下安装PostgreSQL9.3

PostgreSQL配置Streaming Replication集群

如何在CentOS 7/6.5/6.4 下安装PostgreSQL 9.3 与 phpPgAdmin 

------------------------------------华丽丽的分割线------------------------------------

PostgreSQL 的详细介绍:请点这里
PostgreSQL 的下载地址:请点这里

本文永久更新链接地址

相关内容