* RelationReloadNailed - reload minimal information for nailed relations. * * The structure of a nailed relation can never change (which is good, because * we rely on knowing their structure to be able to read catalog content). But * some parts, e.g. pg_class.relfrozenxid, are still important to have * accurate content for. Therefore those need to be reloaded after the arrival * of invalidat
| 2444 | * of invalidations. |
| 2445 | */ |
| 2446 | static void |
| 2447 | RelationReloadNailed(Relation relation) |
| 2448 | { |
| 2449 | Assert(relation->rd_isnailed); |
| 2450 | |
| 2451 | /* |
| 2452 | * Redo RelationInitPhysicalAddr in case it is a mapped relation whose |
| 2453 | * mapping changed. |
| 2454 | */ |
| 2455 | RelationInitPhysicalAddr(relation); |
| 2456 | |
| 2457 | /* flag as needing to be revalidated */ |
| 2458 | relation->rd_isvalid = false; |
| 2459 | |
| 2460 | /* |
| 2461 | * Can only reread catalog contents if in a transaction. If the relation |
| 2462 | * is currently open (not counting the nailed refcount), do so |
| 2463 | * immediately. Otherwise we've already marked the entry as possibly |
| 2464 | * invalid, and it'll be fixed when next opened. |
| 2465 | */ |
| 2466 | if (!IsTransactionState() || relation->rd_refcnt <= 1) |
| 2467 | return; |
| 2468 | |
| 2469 | if (relation->rd_rel->relkind == RELKIND_INDEX) |
| 2470 | { |
| 2471 | /* |
| 2472 | * If it's a nailed-but-not-mapped index, then we need to re-read the |
| 2473 | * pg_class row to see if its relfilenode changed. |
| 2474 | */ |
| 2475 | RelationReloadIndexInfo(relation); |
| 2476 | } |
| 2477 | else |
| 2478 | { |
| 2479 | /* |
| 2480 | * Reload a non-index entry. We can't easily do so if relcaches |
| 2481 | * aren't yet built, but that's fine because at that stage the |
| 2482 | * attributes that need to be current (like relfrozenxid) aren't yet |
| 2483 | * accessed. To ensure the entry will later be revalidated, we leave |
| 2484 | * it in invalid state, but allow use (cf. RelationIdGetRelation()). |
| 2485 | */ |
| 2486 | if (criticalRelcachesBuilt) |
| 2487 | { |
| 2488 | HeapTuple pg_class_tuple; |
| 2489 | Form_pg_class relp; |
| 2490 | |
| 2491 | /* |
| 2492 | * NB: Mark the entry as valid before starting to scan, to avoid |
| 2493 | * self-recursion when re-building pg_class. |
| 2494 | */ |
| 2495 | relation->rd_isvalid = true; |
| 2496 | |
| 2497 | pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), |
| 2498 | true, false); |
| 2499 | relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); |
| 2500 | memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE); |
| 2501 | heap_freetuple(pg_class_tuple); |
| 2502 | |
| 2503 | /* |
no test coverage detected