我使用Postgres行级安全来锁定所有跨表查询到特定的租户。我通过调用SET app.tenant_id = x;
语句每次我的服务打开一个连接,我的RLS策略使用这个会话级设置来限制返回的数据。基本上是在'Alternative Approach'下描述的here方法。
如果此服务部署在AWS中,并且RDS代理位于它和数据库之间,那么我知道它将受到“连接固定”的影响,因为我使用的是SET
语句。我试图了解这个问题到底有多大。几个问题:
SET LOCAL
语句也会导致固定吗?- 如果我到RDS代理的服务连接是短期的,并且是单个事务(99%的情况下是这样),这是否会减少影响?
- 服务连接池(服务-〉RDS代理)是有帮助还是有阻碍?
基本上任何关于这是一个多大的问题,我如何使这个工作,或任何变通办法的建议,将不胜感激。
1条答案
按热度按时间wpx232ag1#
我明白你的意思。根据文档,
SET
会导致钉扎,但不清楚这是否包括SET LOCAL
。因为我也需要这些信息,我今天将运行一个测试,并在这里发布结果。我将执行以下操作
步骤1:通过我们的代理打开一个连接,并使用常规的
SET
,以确保DatabaseConnectionsCurrentlySessionPinned
指标增加到1。第2步:我将关闭该连接,并看到指标降回到0。
步骤3:我将打开一个新连接,但这次我将使用以下查询:
第4步:我将关闭连接,如果连接被固定,我将监视指标,看看它是否以及何时会减回0。
让我们开始吧
正如预期的那样,当我运行
SET
命令时,代理和服务器之间的连接立即被固定。当我关闭客户端和代理之间的连接时,代理和服务器之间的固定连接立即关闭。
当我运行
SET LOCAL
命令时,代理和服务器之间的连接没有固定。连接未固定,因此此步骤是多余的。
结论
SET LOCAL
确实避免了RDS代理中的固定,但警告必须在事务中完成。在我之前尝试回答这个问题时,pgAdmin的行为使我得出结论,在这两种情况下都会发生固定,这是错误的。
为了回答您的其他问题,如果发生了固定,则事务是否短并不重要。服务器连接将保持固定,直到客户端连接消失。唯一的解决办法是确保在客户端连接固定后立即关闭它们。
该文档指出,"当连接被固定时,每个后续事务使用相同的底层数据库连接,直到会话结束。其他客户端连接也不能重用该数据库连接,直到会话结束。当客户端连接断开时,会话结束。"