原文地址:“READ-ONLY” MODE FOR POSTGRESQL
原文作者:Jonathan Katz(乔纳森·卡茨)
介绍
一般,我们在使用Postgresql数据库的只读模式时,需要考虑具体的使用场景。
想要达到只读查询的目的,我们有多种方法(查询语句,在不调用VOLATILE函数去修改数据)
例如:
1、使用Pgpool-II的软代理
2、使用Django软件开发框架下的查询代理。
但是,在一些情况下,我们需要Postgresql(读写库)数据库的主节点,能够实现只读模式连接。
例如:
1、当把应用程序置于降级状态下,执行数据库的迁移或者数据库的升级。
2、管理员在查看逐渐增长的预写系统日志,这些是跟踪记录系统变化的日志。
PostgreSQL has a configuration parameter call default_transaction_read_only. Setting globally to forces all connections to disallow writes to the database. is a reloadable parameter, so you do not need to restart your Postgres instance to use it.default_transaction_read_onlyondefault_transaction_read_only
Here is a quick example of how works. First, ensure your system does not have set:default_transaction_read_onlydefault_transaction_read_only
PostgreSQL有一个可调用的配置参数:default_transaction_read_only。它是全局设置,可以强制所有连接禁止写入数据库。 这个参数是一个可重载的参数,因此您无需重新启动 Postgres 实例即可使它生效。default_transaction_read_only的值为on
示例
下面是一个工作原理的简单示例。
首先,确保您的系统未修改过此参数:default_transaction_read_only
查询参数的值
postgres=# SHOW default_transaction_read_only ;
default_transaction_read_only
-------------------------------
off
(1 row)
postgres=# CREATE TABLE IF NOT EXISTS abc (id int);
INSERT INTO abc VALUES (1) RETURNING id;
CREATE TABLE
id
----
1
(1 row)
INSERT 0 1
这符合我们的预期:
我们能够创建一个表并插入数据。现在让我们将系统置于只读模式
(请注意,我在PostgreSQL 14上运行它default_transaction_read_only)
ALTER SYSTEM SET default_transaction_read_only TO on;
SELECT pg_reload_conf();
SHOW default_transaction_read_only;
确保已启用default_transaction_read_onl参数
查看参数的值
postgres=# SHOW default_transaction_read_only;
default_transaction_read_only
-------------------------------
on
(1 row)
现在验证是否允许写入:
postgres=# INSERT INTO abc VALUES (2) RETURNING id;
ERROR: cannot execute INSERT in a read-only transaction
非常好!发现插入命令报错
请注意,这不是一劳永逸的:这里有一些注意事项关于default_transaction_read_only
首先,可以在会话中覆盖(会话的优先级高),即使该值在数据库内设置的是只读。
例如:default_transaction_read_only的值是on
如果在会话中设置了off,只读也是无效的。
postgres=# SHOW default_transaction_read_only ;
default_transaction_read_only
-------------------------------
on
(1 row)
postgres=# SET default_transaction_read_only TO off;
SET
postgres=# INSERT INTO abc VALUES (2) RETURNING id;
id
----
2
(1 row)
INSERT 0 1
其次,在使用应用程序时,还必须确保可以将应用配置为仅向数据库发送读取查询,从而确保流畅的用户体验。
如果此时还有大量的写请求,会有大量的报错产生。
总结
也就是说,如果您遇到需要将PostgreSQL主实例暂时置于只读模式的情况,则可以使用来防止写入事务。




