您可以使用 cloudsql_session_read_only 会话参数创建只读的 Cloud SQL for PostgreSQL 会话。与标准的 PostgreSQL 只读选项相比,这种方法可以更可靠地防止在会话期间修改数据。使用 cloudsql_session_read_only 参数,您可以暂时或永久(在会话期间)将会话设为只读。您可以在各种情境下使用此类只读会话来帮助保护数据完整性,包括使用 Model Context Protocol (MCP) 工具、报告工具和审核工具的会话。
默认情况下,cloudsql_session_read_only 设置为 off,这允许修改数据。
只读模式可防止哪些操作
在只读会话中,数据库无法修改任何数据。具体来说,只读模式可防止以下操作:
只读模式会阻止生成新的交易 ID。 无法启动任何可写事务,因此无法执行任何数据操纵语言 (DML) 或数据定义语言 (DDL) 指令。不过,如果在活跃的可写事务中间设置了该标志,则可以执行基本的 DML 和 DDL 指令,直到事务终止。
只读模式会阻止以下类型的语句和调用:
- 类似
VACUUM和NOTIFY的语句。 - 具有副作用的函数。这意味着,您无法调用
FUNCTION或执行定义为VOLATILE和LANGUAGE C或LANGUAGE internal的PROCEDURE,因为它们的部分副作用不需要交易 ID。例如,pg_promote()、pg_cancel_backend()和pg_terminate_backend()。 - 外部数据封装容器。
- 您使用 SQL 过程语言 (PL) 创建的任何函数或过程。
- 类似
配置只读状态
在 Cloud SQL for PostgreSQL 会话期间,您可以使用 SET 语句更改 cloudsql_session_read_only 标志的值,如下所示:
SET cloudsql_session_read_only = 'on'此语句会将会话设为只读,只要该标志仍设置为
on,任何人就都无法修改数据。如需在会话中稍后继续修改数据,请将值更改回off:SET cloudsql_session_read_only = 'off'将标志设置回
off可恢复会话中的写入权限,除非该标志设置为locked。SET cloudsql_session_read_only = 'locked'将标志设置为
locked会使会话永久处于只读状态。 将标志设置为locked后,在会话期间,您无法将该标志更改为任何其他值。
如需在连接到数据库后立即将会话永久设为只读,请将 cloudsql_session_read_only 标志嵌入会话的连接字符串中:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE?options=-ccloudsql_session_read_only=locked
进行以下替换:
- USER:创建会话的用户的用户名。
- PASSWORD:用户的密码。
- HOST:主机网址。
- PORT:端口号
- DATABASE:数据库名称。
这种方法的另一个优点是,如果您尝试连接到不支持只读会话的旧版 Cloud SQL,则连接会失败。
您还可以拒绝特定数据库用户的所有未来连接的写入访问权限,如下所示:
ALTER USER USERNAME SET cloudsql_session_read_only = 'locked';
将 USERNAME 替换为您要将访问权限限制为只读权限的用户的用户名。
在只读会话中启用特定功能
- 您可以启用对定义为
VOLATILE和LANGUAGE C或LANGUAGE internal的特定FUNCTION或PROCEDURE的使用。为此,请将SECURITY LABEL附加到设置为allow的函数或过程。 - 如需禁止在会话中使用特定函数,请将
SECURITY LABEL语句设置为deny。 如需将不影响全局状态的函数列入许可名单,请创建一组预定义的安全标签:
CREATE EXTENSION "google_read_only_session"google_read_only_session扩展程序可实现以下功能:- 所有允许在只读模式下使用的内置易失性 C 函数。
- 数据库中加载的扩展程序中允许用于只读模式的所有函数,包括
pl/pgsql和pl/v8语言的处理函数。
如果您之后安装了一个或多个新扩展程序,则需要先舍弃
google_read_only_session扩展程序,然后再重新创建该扩展程序,才能应用组标签:> DROP EXTENSION google_read_only_session; > CREATE EXTENSION google_read_only_session;DROP命令不会移除任何现有标签。第二个CREATE命令只是为新扩展中的不稳定 C 函数添加标签。