Re: bogus: logical replication rows/cols combinations - Mailing list pgsql-hackers
From | Tomas Vondra |
---|---|
Subject | Re: bogus: logical replication rows/cols combinations |
Date | |
Msg-id | 7c5b09ee-7d97-9038-3857-dc20c966b50c@enterprisedb.com Whole thread Raw |
In response to | Re: bogus: logical replication rows/cols combinations (Amit Kapila <amit.kapila16@gmail.com>) |
Responses |
Re: bogus: logical replication rows/cols combinations
|
List | pgsql-hackers |
Hi, so I've been looking at tweaking the code so that the behavior matches Alvaro's expectations. It passes check-world but I'm not claiming it's nowhere near commitable - the purpose is mostly to give better idea of how invasive the change is etc. As described earlier, this abandons the idea of building a single OR expression from all the row filters (per action), and replaces that with a list of per-publication info (struct PublicationInfo), combining info about both row filters and column lists. This means we can't initialize the row filters and column lists separately, but at the same time. So pgoutput_row_filter_init was modified to initialize both, and pgoutput_column_list_init was removed. With this info, we can calculate column lists only for publications with matching row filters, which is what the modified pgoutput_row_filter does (the calculated column list is returned through a parameter). This however does not remove the 'columns' from RelationSyncEntry entirely. We still need that "superset" column list when sending schema. Imagine two publications, one replicating (a,b) and the other (a,c), maybe depending on row filter. send_relation_and_attrs() needs to send info about all three attributes (a,b,c), i.e. about any attribute that might end up being replicated. We might try to be smarter and send the exact schema needed by the next operation, i.e. when inserting (a,b) we'd make sure the last schema we sent was (a,b) and invalidate/resend it otherwise. But that might easily result in "trashing" where we send the schema and the next operation invalidates it right away because it needs a different schema. But there's another reason to do it like this - it seems desirable to actually reset columns don't match the calculated column list. Using Alvaro's example, it seems reasonable to expect these two transactions to produce the same result on the subscriber: 1) insert (a,b) + update to (a,c) insert into uno values (1, 2, 3); update uno set a = -1 where a = 1; 2) insert (a,c) insert into uno values (-1, 2, 3); But to do this, the update actually needs to send (-1,NULL,3). So in this case we'll have (a,b,c) column list in RelationSyncEntry, and only attributes on this list will be sent as part of schema. And DML actions we'll calculate either (a,b) or (a,c) depending on the row filter, and missing attributes will be replicated as NULL. I haven't done any tests how this affect performance, but I have a couple thoughts regarding that: a) I kinda doubt the optimizations would really matter in practice, because how likely is it that one relation is in many publications (in the same subscription)? b) Did anyone actually do some benchmarks that I could repeat, to see how much worse this is? c) AFAICS we could optimize this in at least some common cases. For example we could combine the entries with matching row filters, and/or column filters. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Attachment
pgsql-hackers by date: