|
123 | 123 | #include "utils/syscache.h"
|
124 | 124 | #include "utils/usercontext.h"
|
125 | 125 |
|
126 |
| -static bool table_states_valid = false; |
| 126 | +typedef enum |
| 127 | +{ |
| 128 | + SYNC_TABLE_STATE_NEEDS_REBUILD, |
| 129 | + SYNC_TABLE_STATE_REBUILD_STARTED, |
| 130 | + SYNC_TABLE_STATE_VALID, |
| 131 | +} SyncingTablesState; |
| 132 | + |
| 133 | +static SyncingTablesState table_states_validity = SYNC_TABLE_STATE_NEEDS_REBUILD; |
127 | 134 | static List *table_states_not_ready = NIL;
|
128 | 135 | static bool FetchTableStates(bool *started_tx);
|
129 | 136 |
|
@@ -273,7 +280,7 @@ wait_for_worker_state_change(char expected_state)
|
273 | 280 | void
|
274 | 281 | invalidate_syncing_table_states(Datum arg, int cacheid, uint32 hashvalue)
|
275 | 282 | {
|
276 |
| - table_states_valid = false; |
| 283 | + table_states_validity = SYNC_TABLE_STATE_NEEDS_REBUILD; |
277 | 284 | }
|
278 | 285 |
|
279 | 286 | /*
|
@@ -1568,13 +1575,15 @@ FetchTableStates(bool *started_tx)
|
1568 | 1575 |
|
1569 | 1576 | *started_tx = false;
|
1570 | 1577 |
|
1571 |
| - if (!table_states_valid) |
| 1578 | + if (table_states_validity != SYNC_TABLE_STATE_VALID) |
1572 | 1579 | {
|
1573 | 1580 | MemoryContext oldctx;
|
1574 | 1581 | List *rstates;
|
1575 | 1582 | ListCell *lc;
|
1576 | 1583 | SubscriptionRelState *rstate;
|
1577 | 1584 |
|
| 1585 | + table_states_validity = SYNC_TABLE_STATE_REBUILD_STARTED; |
| 1586 | + |
1578 | 1587 | /* Clean the old lists. */
|
1579 | 1588 | list_free_deep(table_states_not_ready);
|
1580 | 1589 | table_states_not_ready = NIL;
|
@@ -1608,7 +1617,15 @@ FetchTableStates(bool *started_tx)
|
1608 | 1617 | has_subrels = (table_states_not_ready != NIL) ||
|
1609 | 1618 | HasSubscriptionRelations(MySubscription->oid);
|
1610 | 1619 |
|
1611 |
| - table_states_valid = true; |
| 1620 | + /* |
| 1621 | + * If the subscription relation cache has been invalidated since we |
| 1622 | + * entered this routine, we still use and return the relations we just |
| 1623 | + * finished constructing, to avoid infinite loops, but we leave the |
| 1624 | + * table states marked as stale so that we'll rebuild it again on next |
| 1625 | + * access. Otherwise, we mark the table states as valid. |
| 1626 | + */ |
| 1627 | + if (table_states_validity == SYNC_TABLE_STATE_REBUILD_STARTED) |
| 1628 | + table_states_validity = SYNC_TABLE_STATE_VALID; |
1612 | 1629 | }
|
1613 | 1630 |
|
1614 | 1631 | return has_subrels;
|
|
0 commit comments