-
Notifications
You must be signed in to change notification settings - Fork 96
Description
I use pgpool in front of several CloudSQL instances (1 primary node, multiple replicas). Most clients only perform simple read-only requests (SELECT), which are perfectly load-balanced by pgpool using statement-level load balancing. Only a few clients perform write requests, which are encapsulated within transactions and routed to the primary node by pgpool.
Now, I want to use PostgreSQL Row-Level Security (RLS) and am wondering: What is the best approach to do so? I’ve tried several methods:
Transaction with role
BEGIN;
SET ROLE ... <- set the role for RLS
SELECT ... <- the actual query
COMMIT;
Transaction with set_config
BEGIN;
SELECT set_config ... <- set config for RLS
SELECT ... <- the actual query
COMMIT;
CTE with set_config
WITH ctx AS (SELECT set_config(...)) <- set config for RLS
SELECT ... FROM ..., ctx WHERE ...;
The problem with all approaches
A SET or set_config always causes the following statements to be routed to the primary node. Even with the CTE solution, which, in my understanding, should not be the case since set_config within a CTE is meant to apply only to the following SELECT statement.
The only solution I found to prevent pgpool from routing everything to the primary is to mark set_config as "read-only" using read_only_function_list or write_function_list.
Question
Can you advise on how to use pgpool with statement-level load balancing enabled alongside row-level security?
Environment
pgpool2 version: 4.7.0
PostgreSQL version: 18.1