* RelationCacheInvalidate * Blow away cached relation descriptors that have zero reference counts, * and rebuild those with positive reference counts. Also reset the smgr * relation cache and re-read relation mapping data. * * Apart from debug_discard_caches, this is currently used only to recover * from SI message buffer overflow, so we do not touch relations having * new-in-transac
| 3053 | * RelationBuildDesc() would become an infinite loop. |
| 3054 | */ |
| 3055 | void |
| 3056 | RelationCacheInvalidate(bool debug_discard) |
| 3057 | { |
| 3058 | HASH_SEQ_STATUS status; |
| 3059 | RelIdCacheEnt *idhentry; |
| 3060 | Relation relation; |
| 3061 | List *rebuildFirstList = NIL; |
| 3062 | List *rebuildList = NIL; |
| 3063 | ListCell *l; |
| 3064 | int i; |
| 3065 | |
| 3066 | /* |
| 3067 | * Reload relation mapping data before starting to reconstruct cache. |
| 3068 | */ |
| 3069 | RelationMapInvalidateAll(); |
| 3070 | |
| 3071 | /* Phase 1 */ |
| 3072 | hash_seq_init(&status, RelationIdCache); |
| 3073 | |
| 3074 | while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) |
| 3075 | { |
| 3076 | relation = idhentry->reldesc; |
| 3077 | |
| 3078 | /* Must close all smgr references to avoid leaving dangling ptrs */ |
| 3079 | RelationCloseSmgr(relation); |
| 3080 | |
| 3081 | /* |
| 3082 | * Ignore new relations; no other backend will manipulate them before |
| 3083 | * we commit. Likewise, before replacing a relation's relfilenode, we |
| 3084 | * shall have acquired AccessExclusiveLock and drained any applicable |
| 3085 | * pending invalidations. |
| 3086 | */ |
| 3087 | if (relation->rd_createSubid != InvalidSubTransactionId || |
| 3088 | relation->rd_firstRelfilenodeSubid != InvalidSubTransactionId) |
| 3089 | continue; |
| 3090 | |
| 3091 | relcacheInvalsReceived++; |
| 3092 | |
| 3093 | if (RelationHasReferenceCountZero(relation)) |
| 3094 | { |
| 3095 | /* Delete this entry immediately */ |
| 3096 | Assert(!relation->rd_isnailed); |
| 3097 | RelationClearRelation(relation, false); |
| 3098 | } |
| 3099 | else |
| 3100 | { |
| 3101 | /* |
| 3102 | * If it's a mapped relation, immediately update its rd_node in |
| 3103 | * case its relfilenode changed. We must do this during phase 1 |
| 3104 | * in case the relation is consulted during rebuild of other |
| 3105 | * relcache entries in phase 2. It's safe since consulting the |
| 3106 | * map doesn't involve any access to relcache entries. |
| 3107 | */ |
| 3108 | if (RelationIsMapped(relation)) |
| 3109 | RelationInitPhysicalAddr(relation); |
| 3110 | |
| 3111 | /* |
| 3112 | * Add this entry to list of stuff to rebuild in second pass. |
no test coverage detected