|
122 | 122 | #include "utils/syscache.h"
|
123 | 123 | #include "utils/usercontext.h"
|
124 | 124 |
|
125 |
| -static bool table_states_valid = false; |
| 125 | +typedef enum |
| 126 | +{ |
| 127 | + SYNC_TABLE_STATE_NEEDS_REBUILD, |
| 128 | + SYNC_TABLE_STATE_REBUILD_STARTED, |
| 129 | + SYNC_TABLE_STATE_VALID, |
| 130 | +} SyncingTablesState; |
| 131 | + |
| 132 | +static SyncingTablesState table_states_validity = SYNC_TABLE_STATE_NEEDS_REBUILD; |
126 | 133 | static List *table_states_not_ready = NIL;
|
127 | 134 | static bool FetchTableStates(bool *started_tx);
|
128 | 135 |
|
@@ -272,7 +279,7 @@ wait_for_worker_state_change(char expected_state)
|
272 | 279 | void
|
273 | 280 | invalidate_syncing_table_states(Datum arg, int cacheid, uint32 hashvalue)
|
274 | 281 | {
|
275 |
| - table_states_valid = false; |
| 282 | + table_states_validity = SYNC_TABLE_STATE_NEEDS_REBUILD; |
276 | 283 | }
|
277 | 284 |
|
278 | 285 | /*
|
@@ -1556,13 +1563,15 @@ FetchTableStates(bool *started_tx)
|
1556 | 1563 |
|
1557 | 1564 | *started_tx = false;
|
1558 | 1565 |
|
1559 |
| - if (!table_states_valid) |
| 1566 | + if (table_states_validity != SYNC_TABLE_STATE_VALID) |
1560 | 1567 | {
|
1561 | 1568 | MemoryContext oldctx;
|
1562 | 1569 | List *rstates;
|
1563 | 1570 | ListCell *lc;
|
1564 | 1571 | SubscriptionRelState *rstate;
|
1565 | 1572 |
|
| 1573 | + table_states_validity = SYNC_TABLE_STATE_REBUILD_STARTED; |
| 1574 | + |
1566 | 1575 | /* Clean the old lists. */
|
1567 | 1576 | list_free_deep(table_states_not_ready);
|
1568 | 1577 | table_states_not_ready = NIL;
|
@@ -1596,7 +1605,15 @@ FetchTableStates(bool *started_tx)
|
1596 | 1605 | has_subrels = (table_states_not_ready != NIL) ||
|
1597 | 1606 | HasSubscriptionRelations(MySubscription->oid);
|
1598 | 1607 |
|
1599 |
| - table_states_valid = true; |
| 1608 | + /* |
| 1609 | + * If the subscription relation cache has been invalidated since we |
| 1610 | + * entered this routine, we still use and return the relations we just |
| 1611 | + * finished constructing, to avoid infinite loops, but we leave the |
| 1612 | + * table states marked as stale so that we'll rebuild it again on next |
| 1613 | + * access. Otherwise, we mark the table states as valid. |
| 1614 | + */ |
| 1615 | + if (table_states_validity == SYNC_TABLE_STATE_REBUILD_STARTED) |
| 1616 | + table_states_validity = SYNC_TABLE_STATE_VALID; |
1600 | 1617 | }
|
1601 | 1618 |
|
1602 | 1619 | return has_subrels;
|
|
0 commit comments