diff --git a/include/spock.h b/include/spock.h index a4bc2563..7eaf2251 100644 --- a/include/spock.h +++ b/include/spock.h @@ -51,6 +51,8 @@ extern int restart_delay_default; extern int restart_delay_on_exception; extern int spock_replay_queue_size; /* Deprecated - no longer used */ extern bool check_all_uc_indexes; +extern bool spock_enable_quiet_mode; + extern char *shorten_hash(const char *str, int maxlen); extern List *textarray_to_list(ArrayType *textarray); diff --git a/patches/15/pg15-015-attoptions.diff b/patches/15/pg15-015-attoptions.diff index 7b63311a..53998f21 100644 --- a/patches/15/pg15-015-attoptions.diff +++ b/patches/15/pg15-015-attoptions.diff @@ -1,5 +1,5 @@ diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c -index 5b696043c5..16ec985928 100644 +index 620602fba2d..8eebc4cde65 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -168,6 +168,15 @@ static relopt_bool boolRelOpts[] = @@ -38,7 +38,7 @@ index 5b696043c5..16ec985928 100644 /* list terminator */ {{NULL}} }; -@@ -2076,7 +2098,9 @@ attribute_reloptions(Datum reloptions, bool validate) +@@ -2085,7 +2107,9 @@ attribute_reloptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)}, @@ -50,10 +50,10 @@ index 5b696043c5..16ec985928 100644 return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c -index 88ab5f99c8..161333c5e0 100644 +index 64044de67b2..d2a86a98987 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c -@@ -66,6 +66,7 @@ +@@ -67,6 +67,7 @@ #include "storage/smgr.h" #include "storage/spin.h" #include "storage/standby.h" @@ -61,7 +61,7 @@ index 88ab5f99c8..161333c5e0 100644 #include "utils/datum.h" #include "utils/inval.h" #include "utils/lsyscache.h" -@@ -86,6 +87,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, +@@ -88,6 +89,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, HeapTuple newtup); static void check_inplace_rel_lock(HeapTuple oldtup); #endif @@ -69,7 +69,7 @@ index 88ab5f99c8..161333c5e0 100644 static Bitmapset *HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, -@@ -117,6 +119,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); +@@ -119,6 +121,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_required, @@ -77,7 +77,7 @@ index 88ab5f99c8..161333c5e0 100644 bool *copy); -@@ -2919,7 +2922,7 @@ l1: +@@ -2959,7 +2962,7 @@ l1: * Compute replica identity tuple before entering the critical section so * we don't PANIC upon a memory allocation failure. */ @@ -86,7 +86,7 @@ index 88ab5f99c8..161333c5e0 100644 /* * If this is the first possibly-multixact-able operation in the current -@@ -3150,6 +3153,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3190,6 +3193,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, Bitmapset *id_attrs; Bitmapset *interesting_attrs; Bitmapset *modified_attrs; @@ -94,7 +94,7 @@ index 88ab5f99c8..161333c5e0 100644 ItemId lp; HeapTupleData oldtup; HeapTuple heaptup; -@@ -3267,6 +3271,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3351,6 +3355,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, modified_attrs = HeapDetermineColumnsInfo(relation, interesting_attrs, id_attrs, &oldtup, newtup, &id_has_external); @@ -102,7 +102,7 @@ index 88ab5f99c8..161333c5e0 100644 /* * If we're not updating any "key" column, we can grab a weaker lock type. -@@ -3538,6 +3543,7 @@ l2: +@@ -3622,6 +3627,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -110,7 +110,7 @@ index 88ab5f99c8..161333c5e0 100644 bms_free(interesting_attrs); return result; } -@@ -3874,6 +3880,7 @@ l2: +@@ -3958,6 +3964,7 @@ l2: old_key_tuple = ExtractReplicaIdentity(relation, &oldtup, bms_overlap(modified_attrs, id_attrs) || id_has_external, @@ -118,7 +118,7 @@ index 88ab5f99c8..161333c5e0 100644 &old_key_copied); /* NO EREPORT(ERROR) from here till changes are logged */ -@@ -4023,6 +4030,7 @@ l2: +@@ -4107,6 +4114,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -126,7 +126,7 @@ index 88ab5f99c8..161333c5e0 100644 bms_free(interesting_attrs); return TM_Ok; -@@ -4195,6 +4203,26 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, +@@ -4279,6 +4287,33 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, } } @@ -138,6 +138,13 @@ index 88ab5f99c8..161333c5e0 100644 + TupleDesc tupdesc = RelationGetDescr(relation); + AttributeOpts *aopt; + ++ /* ++ * Catalog relations are never sent by LR, no chance to use the delta_apply ++ * feature ++ */ ++ if (IsCatalogRelation(relation)) ++ return NULL; ++ + for (attnum = 1; attnum <= tupdesc->natts; attnum++) + { + aopt = get_attribute_options(relation->rd_id, attnum); @@ -153,7 +160,7 @@ index 88ab5f99c8..161333c5e0 100644 /* * Check which columns are being updated. * -@@ -8913,6 +8941,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) +@@ -9069,6 +9104,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) */ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, @@ -161,7 +168,7 @@ index 88ab5f99c8..161333c5e0 100644 bool *copy) { TupleDesc desc = RelationGetDescr(relation); -@@ -8945,13 +8974,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, +@@ -9101,13 +9137,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, } /* if the key isn't required and we're only logging the key, we're done */ @@ -180,7 +187,7 @@ index 88ab5f99c8..161333c5e0 100644 * If there's no defined replica identity columns, treat as !key_required. * (This case should not be reachable from heap_update, since that should diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h -index ee37af9500..98b48a8fd8 100644 +index ee37af95001..98b48a8fd89 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -21,6 +21,8 @@ typedef struct AttributeOpts diff --git a/patches/16/pg16-015-attoptions.diff b/patches/16/pg16-015-attoptions.diff index ffea2382..53998f21 100644 --- a/patches/16/pg16-015-attoptions.diff +++ b/patches/16/pg16-015-attoptions.diff @@ -1,5 +1,5 @@ diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c -index 469de9bb49..0119e5aa7c 100644 +index 620602fba2d..8eebc4cde65 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -168,6 +168,15 @@ static relopt_bool boolRelOpts[] = @@ -38,7 +38,7 @@ index 469de9bb49..0119e5aa7c 100644 /* list terminator */ {{NULL}} }; -@@ -2072,7 +2094,9 @@ attribute_reloptions(Datum reloptions, bool validate) +@@ -2085,7 +2107,9 @@ attribute_reloptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)}, @@ -50,7 +50,7 @@ index 469de9bb49..0119e5aa7c 100644 return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c -index 723e34e464..b2f845211d 100644 +index 64044de67b2..d2a86a98987 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -67,6 +67,7 @@ @@ -61,7 +61,7 @@ index 723e34e464..b2f845211d 100644 #include "utils/datum.h" #include "utils/inval.h" #include "utils/lsyscache.h" -@@ -87,6 +88,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, +@@ -88,6 +89,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, HeapTuple newtup); static void check_inplace_rel_lock(HeapTuple oldtup); #endif @@ -69,15 +69,15 @@ index 723e34e464..b2f845211d 100644 static Bitmapset *HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, -@@ -121,6 +123,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); +@@ -119,6 +121,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); - static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, + static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_required, + Bitmapset *logged_old_attrs, bool *copy); -@@ -2780,7 +2783,7 @@ l1: +@@ -2959,7 +2962,7 @@ l1: * Compute replica identity tuple before entering the critical section so * we don't PANIC upon a memory allocation failure. */ @@ -86,7 +86,7 @@ index 723e34e464..b2f845211d 100644 /* * If this is the first possibly-multixact-able operation in the current -@@ -3013,6 +3016,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3190,6 +3193,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, Bitmapset *id_attrs; Bitmapset *interesting_attrs; Bitmapset *modified_attrs; @@ -94,7 +94,7 @@ index 723e34e464..b2f845211d 100644 ItemId lp; HeapTupleData oldtup; HeapTuple heaptup; -@@ -3135,6 +3139,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3351,6 +3355,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, modified_attrs = HeapDetermineColumnsInfo(relation, interesting_attrs, id_attrs, &oldtup, newtup, &id_has_external); @@ -102,7 +102,7 @@ index 723e34e464..b2f845211d 100644 /* * If we're not updating any "key" column, we can grab a weaker lock type. -@@ -3409,6 +3414,7 @@ l2: +@@ -3622,6 +3627,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -110,7 +110,7 @@ index 723e34e464..b2f845211d 100644 bms_free(interesting_attrs); return result; } -@@ -3758,6 +3764,7 @@ l2: +@@ -3958,6 +3964,7 @@ l2: old_key_tuple = ExtractReplicaIdentity(relation, &oldtup, bms_overlap(modified_attrs, id_attrs) || id_has_external, @@ -118,7 +118,7 @@ index 723e34e464..b2f845211d 100644 &old_key_copied); /* NO EREPORT(ERROR) from here till changes are logged */ -@@ -3924,6 +3931,7 @@ l2: +@@ -4107,6 +4114,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -126,7 +126,7 @@ index 723e34e464..b2f845211d 100644 bms_free(interesting_attrs); return TM_Ok; -@@ -4096,6 +4104,26 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, +@@ -4279,6 +4287,33 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, } } @@ -138,6 +138,13 @@ index 723e34e464..b2f845211d 100644 + TupleDesc tupdesc = RelationGetDescr(relation); + AttributeOpts *aopt; + ++ /* ++ * Catalog relations are never sent by LR, no chance to use the delta_apply ++ * feature ++ */ ++ if (IsCatalogRelation(relation)) ++ return NULL; ++ + for (attnum = 1; attnum <= tupdesc->natts; attnum++) + { + aopt = get_attribute_options(relation->rd_id, attnum); @@ -153,7 +160,7 @@ index 723e34e464..b2f845211d 100644 /* * Check which columns are being updated. * -@@ -9051,6 +9079,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) +@@ -9069,6 +9104,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) */ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, @@ -161,7 +168,7 @@ index 723e34e464..b2f845211d 100644 bool *copy) { TupleDesc desc = RelationGetDescr(relation); -@@ -9083,13 +9112,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, +@@ -9101,13 +9137,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, } /* if the key isn't required and we're only logging the key, we're done */ @@ -180,7 +187,7 @@ index 723e34e464..b2f845211d 100644 * If there's no defined replica identity columns, treat as !key_required. * (This case should not be reachable from heap_update, since that should diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h -index e4119b6aa2..6354a98157 100644 +index ee37af95001..98b48a8fd89 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -21,6 +21,8 @@ typedef struct AttributeOpts @@ -191,4 +198,4 @@ index e4119b6aa2..6354a98157 100644 + Oid delta_apply_function; } AttributeOpts; - extern AttributeOpts *get_attribute_options(Oid attrelid, int attnum); + extern AttributeOpts *get_attribute_options(Oid spcid, int attnum); diff --git a/patches/17/pg17-015-attoptions.diff b/patches/17/pg17-015-attoptions.diff index df156695..53998f21 100644 --- a/patches/17/pg17-015-attoptions.diff +++ b/patches/17/pg17-015-attoptions.diff @@ -1,8 +1,8 @@ diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c -index d6eb5d85599..4ef2e55cc44 100644 +index 620602fba2d..8eebc4cde65 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c -@@ -166,6 +166,15 @@ static relopt_bool boolRelOpts[] = +@@ -168,6 +168,15 @@ static relopt_bool boolRelOpts[] = }, true }, @@ -18,7 +18,7 @@ index d6eb5d85599..4ef2e55cc44 100644 /* list terminator */ {{NULL}} }; -@@ -546,6 +555,19 @@ static relopt_enum enumRelOpts[] = +@@ -548,6 +557,19 @@ static relopt_enum enumRelOpts[] = static relopt_string stringRelOpts[] = { @@ -38,7 +38,7 @@ index d6eb5d85599..4ef2e55cc44 100644 /* list terminator */ {{NULL}} }; -@@ -2070,7 +2092,9 @@ attribute_reloptions(Datum reloptions, bool validate) +@@ -2085,7 +2107,9 @@ attribute_reloptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)}, @@ -50,18 +50,18 @@ index d6eb5d85599..4ef2e55cc44 100644 return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c -index 95e3be524a7..708d55b2618 100644 +index 64044de67b2..d2a86a98987 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c -@@ -64,6 +64,7 @@ - #include "storage/predicate.h" - #include "storage/procarray.h" +@@ -67,6 +67,7 @@ + #include "storage/smgr.h" + #include "storage/spin.h" #include "storage/standby.h" +#include "utils/attoptcache.h" #include "utils/datum.h" - #include "utils/injection_point.h" #include "utils/inval.h" -@@ -85,6 +86,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, + #include "utils/lsyscache.h" +@@ -88,6 +89,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, HeapTuple newtup); static void check_inplace_rel_lock(HeapTuple oldtup); #endif @@ -69,15 +69,15 @@ index 95e3be524a7..708d55b2618 100644 static Bitmapset *HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, -@@ -121,6 +123,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); +@@ -119,6 +121,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); - static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, + static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_required, + Bitmapset *logged_old_attrs, bool *copy); -@@ -2938,7 +2941,7 @@ l1: +@@ -2959,7 +2962,7 @@ l1: * Compute replica identity tuple before entering the critical section so * we don't PANIC upon a memory allocation failure. */ @@ -86,7 +86,7 @@ index 95e3be524a7..708d55b2618 100644 /* * If this is the first possibly-multixact-able operation in the current -@@ -3171,6 +3174,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3190,6 +3193,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, Bitmapset *id_attrs; Bitmapset *interesting_attrs; Bitmapset *modified_attrs; @@ -94,7 +94,7 @@ index 95e3be524a7..708d55b2618 100644 ItemId lp; HeapTupleData oldtup; HeapTuple heaptup; -@@ -3338,6 +3342,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3351,6 +3355,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, modified_attrs = HeapDetermineColumnsInfo(relation, interesting_attrs, id_attrs, &oldtup, newtup, &id_has_external); @@ -102,7 +102,7 @@ index 95e3be524a7..708d55b2618 100644 /* * If we're not updating any "key" column, we can grab a weaker lock type. -@@ -3612,6 +3617,7 @@ l2: +@@ -3622,6 +3627,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -110,7 +110,7 @@ index 95e3be524a7..708d55b2618 100644 bms_free(interesting_attrs); return result; } -@@ -3961,6 +3967,7 @@ l2: +@@ -3958,6 +3964,7 @@ l2: old_key_tuple = ExtractReplicaIdentity(relation, &oldtup, bms_overlap(modified_attrs, id_attrs) || id_has_external, @@ -118,7 +118,7 @@ index 95e3be524a7..708d55b2618 100644 &old_key_copied); /* NO EREPORT(ERROR) from here till changes are logged */ -@@ -4127,6 +4134,7 @@ l2: +@@ -4107,6 +4114,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -126,7 +126,7 @@ index 95e3be524a7..708d55b2618 100644 bms_free(interesting_attrs); return TM_Ok; -@@ -4299,6 +4307,26 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, +@@ -4279,6 +4287,33 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, } } @@ -138,6 +138,13 @@ index 95e3be524a7..708d55b2618 100644 + TupleDesc tupdesc = RelationGetDescr(relation); + AttributeOpts *aopt; + ++ /* ++ * Catalog relations are never sent by LR, no chance to use the delta_apply ++ * feature ++ */ ++ if (IsCatalogRelation(relation)) ++ return NULL; ++ + for (attnum = 1; attnum <= tupdesc->natts; attnum++) + { + aopt = get_attribute_options(relation->rd_id, attnum); @@ -153,7 +160,7 @@ index 95e3be524a7..708d55b2618 100644 /* * Check which columns are being updated. * -@@ -9076,6 +9104,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) +@@ -9069,6 +9104,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) */ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, @@ -161,7 +168,7 @@ index 95e3be524a7..708d55b2618 100644 bool *copy) { TupleDesc desc = RelationGetDescr(relation); -@@ -9108,13 +9137,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, +@@ -9101,13 +9137,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, } /* if the key isn't required and we're only logging the key, we're done */ @@ -180,7 +187,7 @@ index 95e3be524a7..708d55b2618 100644 * If there's no defined replica identity columns, treat as !key_required. * (This case should not be reachable from heap_update, since that should diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h -index a1a9bfc0fb9..e9b6dfab474 100644 +index ee37af95001..98b48a8fd89 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -21,6 +21,8 @@ typedef struct AttributeOpts @@ -191,4 +198,4 @@ index a1a9bfc0fb9..e9b6dfab474 100644 + Oid delta_apply_function; } AttributeOpts; - extern AttributeOpts *get_attribute_options(Oid attrelid, int attnum); + extern AttributeOpts *get_attribute_options(Oid spcid, int attnum); diff --git a/patches/18/pg18-015-attoptions.diff b/patches/18/pg18-015-attoptions.diff index dd42114d..53998f21 100644 --- a/patches/18/pg18-015-attoptions.diff +++ b/patches/18/pg18-015-attoptions.diff @@ -1,8 +1,8 @@ diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c -index 50747c16396..6cdbbe1d0dd 100644 +index 620602fba2d..8eebc4cde65 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c -@@ -166,6 +166,15 @@ static relopt_bool boolRelOpts[] = +@@ -168,6 +168,15 @@ static relopt_bool boolRelOpts[] = }, true }, @@ -18,7 +18,7 @@ index 50747c16396..6cdbbe1d0dd 100644 /* list terminator */ {{NULL}} }; -@@ -557,6 +566,19 @@ static relopt_enum enumRelOpts[] = +@@ -548,6 +557,19 @@ static relopt_enum enumRelOpts[] = static relopt_string stringRelOpts[] = { @@ -38,7 +38,7 @@ index 50747c16396..6cdbbe1d0dd 100644 /* list terminator */ {{NULL}} }; -@@ -2106,7 +2128,9 @@ attribute_reloptions(Datum reloptions, bool validate) +@@ -2085,7 +2107,9 @@ attribute_reloptions(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)}, @@ -50,18 +50,18 @@ index 50747c16396..6cdbbe1d0dd 100644 return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c -index 0dcd6ee817e..dcf26167cae 100644 +index 64044de67b2..d2a86a98987 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c -@@ -48,6 +48,7 @@ - #include "storage/lmgr.h" - #include "storage/predicate.h" - #include "storage/procarray.h" +@@ -67,6 +67,7 @@ + #include "storage/smgr.h" + #include "storage/spin.h" + #include "storage/standby.h" +#include "utils/attoptcache.h" #include "utils/datum.h" - #include "utils/injection_point.h" #include "utils/inval.h" -@@ -67,6 +68,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, + #include "utils/lsyscache.h" +@@ -88,6 +89,7 @@ static void check_lock_if_inplace_updateable_rel(Relation relation, HeapTuple newtup); static void check_inplace_rel_lock(HeapTuple oldtup); #endif @@ -69,15 +69,15 @@ index 0dcd6ee817e..dcf26167cae 100644 static Bitmapset *HeapDetermineColumnsInfo(Relation relation, Bitmapset *interesting_cols, Bitmapset *external_cols, -@@ -104,6 +106,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); +@@ -119,6 +121,7 @@ static void index_delete_sort(TM_IndexDeleteOp *delstate); static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); - static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, + static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_required, + Bitmapset *logged_old_attrs, bool *copy); -@@ -3016,7 +3019,7 @@ l1: +@@ -2959,7 +2962,7 @@ l1: * Compute replica identity tuple before entering the critical section so * we don't PANIC upon a memory allocation failure. */ @@ -86,7 +86,7 @@ index 0dcd6ee817e..dcf26167cae 100644 /* * If this is the first possibly-multixact-able operation in the current -@@ -3249,6 +3252,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3190,6 +3193,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, Bitmapset *id_attrs; Bitmapset *interesting_attrs; Bitmapset *modified_attrs; @@ -94,20 +94,15 @@ index 0dcd6ee817e..dcf26167cae 100644 ItemId lp; HeapTupleData oldtup; HeapTuple heaptup; -@@ -3419,6 +3423,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, +@@ -3351,6 +3355,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, + modified_attrs = HeapDetermineColumnsInfo(relation, interesting_attrs, id_attrs, &oldtup, newtup, &id_has_external); ++ logged_old_attrs = HeapDetermineLogOldColumns(relation); -+ if (!IsCatalogRelationOid(relation->rd_id)) -+ logged_old_attrs = HeapDetermineLogOldColumns(relation); -+ else -+ /* No need to log old values for catalog tables */ -+ logged_old_attrs = NULL; -+ /* * If we're not updating any "key" column, we can grab a weaker lock type. - * This allows for more concurrency when we are running simultaneously -@@ -3692,6 +3702,7 @@ l2: +@@ -3622,6 +3627,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -115,7 +110,7 @@ index 0dcd6ee817e..dcf26167cae 100644 bms_free(interesting_attrs); return result; } -@@ -4041,6 +4052,7 @@ l2: +@@ -3958,6 +3964,7 @@ l2: old_key_tuple = ExtractReplicaIdentity(relation, &oldtup, bms_overlap(modified_attrs, id_attrs) || id_has_external, @@ -123,7 +118,7 @@ index 0dcd6ee817e..dcf26167cae 100644 &old_key_copied); /* NO EREPORT(ERROR) from here till changes are logged */ -@@ -4207,6 +4219,7 @@ l2: +@@ -4107,6 +4114,7 @@ l2: bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -131,7 +126,7 @@ index 0dcd6ee817e..dcf26167cae 100644 bms_free(interesting_attrs); return TM_Ok; -@@ -4379,6 +4392,26 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, +@@ -4279,6 +4287,33 @@ heap_attr_equals(TupleDesc tupdesc, int attrnum, Datum value1, Datum value2, } } @@ -143,6 +138,13 @@ index 0dcd6ee817e..dcf26167cae 100644 + TupleDesc tupdesc = RelationGetDescr(relation); + AttributeOpts *aopt; + ++ /* ++ * Catalog relations are never sent by LR, no chance to use the delta_apply ++ * feature ++ */ ++ if (IsCatalogRelation(relation)) ++ return NULL; ++ + for (attnum = 1; attnum <= tupdesc->natts; attnum++) + { + aopt = get_attribute_options(relation->rd_id, attnum); @@ -158,7 +160,7 @@ index 0dcd6ee817e..dcf26167cae 100644 /* * Check which columns are being updated. * -@@ -9132,6 +9165,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) +@@ -9069,6 +9104,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) */ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, @@ -166,7 +168,7 @@ index 0dcd6ee817e..dcf26167cae 100644 bool *copy) { TupleDesc desc = RelationGetDescr(relation); -@@ -9164,13 +9198,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, +@@ -9101,13 +9137,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_required, } /* if the key isn't required and we're only logging the key, we're done */ @@ -185,7 +187,7 @@ index 0dcd6ee817e..dcf26167cae 100644 * If there's no defined replica identity columns, treat as !key_required. * (This case should not be reachable from heap_update, since that should diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h -index f684a772af5..6c965fede13 100644 +index ee37af95001..98b48a8fd89 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -21,6 +21,8 @@ typedef struct AttributeOpts @@ -196,4 +198,4 @@ index f684a772af5..6c965fede13 100644 + Oid delta_apply_function; } AttributeOpts; - extern AttributeOpts *get_attribute_options(Oid attrelid, int attnum); + extern AttributeOpts *get_attribute_options(Oid spcid, int attnum); diff --git a/sql/spock--6.0.0-devel.sql b/sql/spock--6.0.0-devel.sql index 1ad9a9a8..8bafafa9 100644 --- a/sql/spock--6.0.0-devel.sql +++ b/sql/spock--6.0.0-devel.sql @@ -355,9 +355,13 @@ CREATE FUNCTION spock.node_info(OUT node_id oid, OUT node_name text, RETURNS record STABLE STRICT LANGUAGE c AS 'MODULE_PATHNAME', 'spock_node_info'; -CREATE FUNCTION spock.spock_gen_slot_name(name, name, name) -RETURNS name -IMMUTABLE STRICT LANGUAGE c AS 'MODULE_PATHNAME'; +CREATE FUNCTION spock.spock_gen_slot_name( + dbname name, + provider_node name, + subscription name +) RETURNS name +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; CREATE FUNCTION spock_version() RETURNS text LANGUAGE c AS 'MODULE_PATHNAME'; @@ -536,20 +540,6 @@ CREATE VIEW spock.lag_tracker AS LEFT JOIN spock.node n ON n.node_id = p.node_id GROUP BY origin.node_name, n.node_name; -CREATE FUNCTION spock.md5_agg_sfunc(text, anyelement) - RETURNS text - LANGUAGE sql -AS -$$ - SELECT md5($1 || $2::text) -$$; -CREATE AGGREGATE spock.md5_agg (ORDER BY anyelement) -( - STYPE = text, - SFUNC = spock.md5_agg_sfunc, - INITCOND = '' -); - -- ---------------------------------------------------------------------- -- Spock Read Only -- ---------------------------------------------------------------------- diff --git a/src/spock.c b/src/spock.c index 27c6ee38..47ad9b75 100644 --- a/src/spock.c +++ b/src/spock.c @@ -132,6 +132,7 @@ int restart_delay_default; int restart_delay_on_exception; int spock_replay_queue_size; /* Deprecated - no longer used */ bool check_all_uc_indexes = false; +bool spock_enable_quiet_mode = false; static emit_log_hook_type prev_emit_log_hook = NULL; static Checkpoint_hook_type prev_Checkpoint_hook = NULL; @@ -970,6 +971,17 @@ _PG_init(void) 0, NULL, NULL, NULL); + DefineCustomBoolVariable("spock.enable_quiet_mode", + "Reduce message verbosity for cleaner output", + "When enabled, downgrades DDL replication INFO/WARNING messages to LOG level " + "and suppresses dependent object reporting in DROP CASCADE operations. " + "Useful for regression tests and production environments where less verbose " + "output is desired.", + &spock_enable_quiet_mode, + false, PGC_SIGHUP, + 0, + NULL, NULL, NULL); + DefineCustomBoolVariable("spock.synchronous_commit", "spock specific synchronous commit value", NULL, diff --git a/src/spock_autoddl.c b/src/spock_autoddl.c index 5aff9ea7..f5c94d8d 100644 --- a/src/spock_autoddl.c +++ b/src/spock_autoddl.c @@ -120,13 +120,14 @@ spock_autoddl_process(PlannedStmt *pstmt, void add_ddl_to_repset(Node *parsetree) { - Relation targetrel; - SpockRepSet *repset; + Relation targetrel; + SpockRepSet *repset; SpockLocalNode *node; - Oid reloid = InvalidOid; - RangeVar *relation = NULL; - List *reloids = NIL; - ListCell *lc; + Oid reloid = InvalidOid; + RangeVar *relation = NULL; + List *reloids = NIL; + ListCell *lc; + bool missing_ok = false; /* no need to proceed if spock_include_ddl_repset is off */ if (!spock_include_ddl_repset) @@ -163,6 +164,8 @@ add_ddl_to_repset(Node *parsetree) { return; } + + missing_ok = ((AlterTableStmt *) parsetree)->missing_ok; } else if (nodeTag(parsetree) == T_CreateStmt) relation = castNode(CreateStmt, parsetree)->relation; @@ -216,7 +219,15 @@ add_ddl_to_repset(Node *parsetree) if (OidIsValid(reloid)) targetrel = RelationIdGetRelation(reloid); else - targetrel = table_openrv(relation, AccessShareLock); + { + targetrel = table_openrv_extended(relation, AccessShareLock, missing_ok); + if (targetrel == NULL) + /* + * If relation doesn't exist - quietly exit. It is assumed that the core + * already produced an INFO message. + */ + return; + } reloid = RelationGetRelid(targetrel); diff --git a/src/spock_dependency.c b/src/spock_dependency.c index 89768537..7bb8af30 100644 --- a/src/spock_dependency.c +++ b/src/spock_dependency.c @@ -707,14 +707,17 @@ reportDependentObjects(const ObjectAddresses *targetObjects, * If no error is to be thrown, and the msglevel is too low to be shown to * either client or server log, there's no need to do any of the work. * + * In quiet mode (spock.enable_quiet_mode), skip reporting dependent + * objects to reduce output verbosity. + * * Note: this code doesn't know all there is to be known about elog * levels, but it works for NOTICE and DEBUG2, which are the only values * msglevel can currently have. We also assume we are running in a normal * operating environment. */ - if (behavior == DROP_CASCADE && + if (spock_enable_quiet_mode || (behavior == DROP_CASCADE && msglevel < my_client_min_messages && - (msglevel < my_log_min_messages || my_log_min_messages == LOG)) + (msglevel < my_log_min_messages || my_log_min_messages == LOG))) return; /* diff --git a/src/spock_functions.c b/src/spock_functions.c index 557c665d..34724ab5 100644 --- a/src/spock_functions.c +++ b/src/spock_functions.c @@ -2343,10 +2343,15 @@ spock_auto_replicate_ddl(const char *query, List *replication_sets, break; } + /* + * Report replication status. In quiet mode, downgrade INFO/WARNING to + * LOG level to reduce output verbosity. + */ if (warn) - elog(WARNING, "DDL statement replicated, but could be unsafe."); + elog(spock_enable_quiet_mode ? LOG : WARNING, + "DDL statement replicated, but could be unsafe."); else - elog(INFO, "DDL statement replicated."); + elog(spock_enable_quiet_mode ? LOG : INFO, "DDL statement replicated."); initStringInfo(&q); if (add_search_path) @@ -2371,7 +2376,7 @@ spock_auto_replicate_ddl(const char *query, List *replication_sets, return; skip_ddl: - elog(WARNING, "This DDL statement will not be replicated."); + elog(spock_enable_quiet_mode ? LOG : WARNING, "This DDL statement will not be replicated."); } diff --git a/src/spock_queue.c b/src/spock_queue.c index b6dc7210..20e43283 100644 --- a/src/spock_queue.c +++ b/src/spock_queue.c @@ -116,7 +116,7 @@ queue_message(List *replication_sets, Oid roleoid, char message_type, /* Cleanup. */ heap_freetuple(tup); - table_close(rel, NoLock); + table_close(rel, RowExclusiveLock); } diff --git a/src/spock_repset.c b/src/spock_repset.c index f0e2bcd1..596184e8 100644 --- a/src/spock_repset.c +++ b/src/spock_repset.c @@ -1087,9 +1087,18 @@ replication_set_add_table(Oid setid, Oid reloid, List *att_list, SpockRepSet *repset = get_replication_set(setid); ObjectAddress referenced; ObjectAddress myself; + LOCKTAG tag; /* Open the relation. */ - targetrel = table_open(reloid, ShareRowExclusiveLock); + SET_LOCKTAG_RELATION(tag, MyDatabaseId, reloid); +#if PG_VERSION_NUM < 170000 + if (!LockOrStrongerHeldByMe(&tag, AccessShareLock)) +#else + if (!LockHeldByMe(&tag, AccessShareLock, true)) +#endif + targetrel = table_open(reloid, AccessShareLock); + else + targetrel = table_open(reloid, NoLock); /* UNLOGGED and TEMP relations cannot be part of replication set. */ if (!RelationNeedsWAL(targetrel)) @@ -1183,9 +1192,18 @@ replication_set_add_seq(Oid setid, Oid seqoid) SpockRepSet *repset = get_replication_set(setid); ObjectAddress referenced; ObjectAddress myself; + LOCKTAG tag; /* Open the relation. */ - targetrel = table_open(seqoid, ShareRowExclusiveLock); + SET_LOCKTAG_RELATION(tag, MyDatabaseId, seqoid); +#if PG_VERSION_NUM < 170000 + if (!LockOrStrongerHeldByMe(&tag, AccessShareLock)) +#else + if (!LockHeldByMe(&tag, AccessShareLock, true)) +#endif + targetrel = table_open(seqoid, AccessShareLock); + else + targetrel = table_open(seqoid, NoLock); /* UNLOGGED and TEMP relations cannot be part of replication set. */ if (!RelationNeedsWAL(targetrel))