@@ -235,7 +235,7 @@ static void ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn,
235
235
static ReorderBufferChange * ReorderBufferIterTXNNext (ReorderBuffer * rb , ReorderBufferIterTXNState * state );
236
236
static void ReorderBufferIterTXNFinish (ReorderBuffer * rb ,
237
237
ReorderBufferIterTXNState * state );
238
- static void ReorderBufferExecuteInvalidations (ReorderBuffer * rb , ReorderBufferTXN * txn );
238
+ static void ReorderBufferExecuteInvalidations (uint32 nmsgs , SharedInvalidationMessage * msgs );
239
239
240
240
/*
241
241
* ---------------------------------------
@@ -486,6 +486,11 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change,
486
486
pfree (change -> data .msg .message );
487
487
change -> data .msg .message = NULL ;
488
488
break ;
489
+ case REORDER_BUFFER_CHANGE_INVALIDATION :
490
+ if (change -> data .inval .invalidations )
491
+ pfree (change -> data .inval .invalidations );
492
+ change -> data .inval .invalidations = NULL ;
493
+ break ;
489
494
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT :
490
495
if (change -> data .snapshot )
491
496
{
@@ -2194,6 +2199,13 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
2194
2199
ReorderBufferApplyMessage (rb , txn , change , streaming );
2195
2200
break ;
2196
2201
2202
+ case REORDER_BUFFER_CHANGE_INVALIDATION :
2203
+ /* Execute the invalidation messages locally */
2204
+ ReorderBufferExecuteInvalidations (
2205
+ change -> data .inval .ninvalidations ,
2206
+ change -> data .inval .invalidations );
2207
+ break ;
2208
+
2197
2209
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT :
2198
2210
/* get rid of the old */
2199
2211
TeardownHistoricSnapshot (false);
@@ -2244,13 +2256,6 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
2244
2256
2245
2257
TeardownHistoricSnapshot (false);
2246
2258
SetupHistoricSnapshot (snapshot_now , txn -> tuplecid_hash );
2247
-
2248
- /*
2249
- * Every time the CommandId is incremented, we could
2250
- * see new catalog contents, so execute all
2251
- * invalidations.
2252
- */
2253
- ReorderBufferExecuteInvalidations (rb , txn );
2254
2259
}
2255
2260
2256
2261
break ;
@@ -2317,7 +2322,7 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
2317
2322
AbortCurrentTransaction ();
2318
2323
2319
2324
/* make sure there's no cache pollution */
2320
- ReorderBufferExecuteInvalidations (rb , txn );
2325
+ ReorderBufferExecuteInvalidations (txn -> ninvalidations , txn -> invalidations );
2321
2326
2322
2327
if (using_subtxn )
2323
2328
RollbackAndReleaseCurrentSubTransaction ();
@@ -2356,7 +2361,8 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
2356
2361
AbortCurrentTransaction ();
2357
2362
2358
2363
/* make sure there's no cache pollution */
2359
- ReorderBufferExecuteInvalidations (rb , txn );
2364
+ ReorderBufferExecuteInvalidations (txn -> ninvalidations ,
2365
+ txn -> invalidations );
2360
2366
2361
2367
if (using_subtxn )
2362
2368
RollbackAndReleaseCurrentSubTransaction ();
@@ -2813,23 +2819,30 @@ ReorderBufferAddNewTupleCids(ReorderBuffer *rb, TransactionId xid,
2813
2819
* Setup the invalidation of the toplevel transaction.
2814
2820
*
2815
2821
* This needs to be called for each XLOG_XACT_INVALIDATIONS message and
2816
- * accumulates all the invalidation messages in the toplevel transaction.
2817
- * This is required because in some cases where we skip processing the
2818
- * transaction (see ReorderBufferForget), we need to execute all the
2819
- * invalidations together.
2822
+ * accumulates all the invalidation messages in the toplevel transaction as
2823
+ * well as in the form of change in reorder buffer. We require to record it in
2824
+ * form of the change so that we can execute only the required invalidations
2825
+ * instead of executing all the invalidations on each CommandId increment. We
2826
+ * also need to accumulate these in the toplevel transaction because in some
2827
+ * cases we skip processing the transaction (see ReorderBufferForget), we need
2828
+ * to execute all the invalidations together.
2820
2829
*/
2821
2830
void
2822
2831
ReorderBufferAddInvalidations (ReorderBuffer * rb , TransactionId xid ,
2823
2832
XLogRecPtr lsn , Size nmsgs ,
2824
2833
SharedInvalidationMessage * msgs )
2825
2834
{
2826
2835
ReorderBufferTXN * txn ;
2836
+ MemoryContext oldcontext ;
2837
+ ReorderBufferChange * change ;
2827
2838
2828
2839
txn = ReorderBufferTXNByXid (rb , xid , true, NULL , lsn , true);
2829
2840
2841
+ oldcontext = MemoryContextSwitchTo (rb -> context );
2842
+
2830
2843
/*
2831
- * We collect all the invalidations under the top transaction so that we
2832
- * can execute them all together.
2844
+ * Collect all the invalidations under the top transaction so that we can
2845
+ * execute them all together. See comment atop this function
2833
2846
*/
2834
2847
if (txn -> toptxn )
2835
2848
txn = txn -> toptxn ;
@@ -2841,8 +2854,7 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid,
2841
2854
{
2842
2855
txn -> ninvalidations = nmsgs ;
2843
2856
txn -> invalidations = (SharedInvalidationMessage * )
2844
- MemoryContextAlloc (rb -> context ,
2845
- sizeof (SharedInvalidationMessage ) * nmsgs );
2857
+ palloc (sizeof (SharedInvalidationMessage ) * nmsgs );
2846
2858
memcpy (txn -> invalidations , msgs ,
2847
2859
sizeof (SharedInvalidationMessage ) * nmsgs );
2848
2860
}
@@ -2856,19 +2868,31 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid,
2856
2868
nmsgs * sizeof (SharedInvalidationMessage ));
2857
2869
txn -> ninvalidations += nmsgs ;
2858
2870
}
2871
+
2872
+ change = ReorderBufferGetChange (rb );
2873
+ change -> action = REORDER_BUFFER_CHANGE_INVALIDATION ;
2874
+ change -> data .inval .ninvalidations = nmsgs ;
2875
+ change -> data .inval .invalidations = (SharedInvalidationMessage * )
2876
+ palloc (sizeof (SharedInvalidationMessage ) * nmsgs );
2877
+ memcpy (change -> data .inval .invalidations , msgs ,
2878
+ sizeof (SharedInvalidationMessage ) * nmsgs );
2879
+
2880
+ ReorderBufferQueueChange (rb , xid , lsn , change , false);
2881
+
2882
+ MemoryContextSwitchTo (oldcontext );
2859
2883
}
2860
2884
2861
2885
/*
2862
2886
* Apply all invalidations we know. Possibly we only need parts at this point
2863
2887
* in the changestream but we don't know which those are.
2864
2888
*/
2865
2889
static void
2866
- ReorderBufferExecuteInvalidations (ReorderBuffer * rb , ReorderBufferTXN * txn )
2890
+ ReorderBufferExecuteInvalidations (uint32 nmsgs , SharedInvalidationMessage * msgs )
2867
2891
{
2868
2892
int i ;
2869
2893
2870
- for (i = 0 ; i < txn -> ninvalidations ; i ++ )
2871
- LocalExecuteInvalidationMessage (& txn -> invalidations [i ]);
2894
+ for (i = 0 ; i < nmsgs ; i ++ )
2895
+ LocalExecuteInvalidationMessage (& msgs [i ]);
2872
2896
}
2873
2897
2874
2898
/*
@@ -3301,6 +3325,24 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
3301
3325
change -> data .msg .message_size );
3302
3326
data += change -> data .msg .message_size ;
3303
3327
3328
+ break ;
3329
+ }
3330
+ case REORDER_BUFFER_CHANGE_INVALIDATION :
3331
+ {
3332
+ char * data ;
3333
+ Size inval_size = sizeof (SharedInvalidationMessage ) *
3334
+ change -> data .inval .ninvalidations ;
3335
+
3336
+ sz += inval_size ;
3337
+
3338
+ ReorderBufferSerializeReserve (rb , sz );
3339
+ data = ((char * ) rb -> outbuf ) + sizeof (ReorderBufferDiskChange );
3340
+
3341
+ /* might have been reallocated above */
3342
+ ondisk = (ReorderBufferDiskChange * ) rb -> outbuf ;
3343
+ memcpy (data , change -> data .inval .invalidations , inval_size );
3344
+ data += inval_size ;
3345
+
3304
3346
break ;
3305
3347
}
3306
3348
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT :
@@ -3578,6 +3620,12 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
3578
3620
3579
3621
break ;
3580
3622
}
3623
+ case REORDER_BUFFER_CHANGE_INVALIDATION :
3624
+ {
3625
+ sz += sizeof (SharedInvalidationMessage ) *
3626
+ change -> data .inval .ninvalidations ;
3627
+ break ;
3628
+ }
3581
3629
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT :
3582
3630
{
3583
3631
Snapshot snap ;
@@ -3844,6 +3892,19 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
3844
3892
change -> data .msg .message_size );
3845
3893
data += change -> data .msg .message_size ;
3846
3894
3895
+ break ;
3896
+ }
3897
+ case REORDER_BUFFER_CHANGE_INVALIDATION :
3898
+ {
3899
+ Size inval_size = sizeof (SharedInvalidationMessage ) *
3900
+ change -> data .inval .ninvalidations ;
3901
+
3902
+ change -> data .inval .invalidations =
3903
+ MemoryContextAlloc (rb -> context , inval_size );
3904
+
3905
+ /* read the message */
3906
+ memcpy (change -> data .inval .invalidations , data , inval_size );
3907
+
3847
3908
break ;
3848
3909
}
3849
3910
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT :
0 commit comments