Skip to content

Add logging for origin changes on delete#383

Open
mason-sharp wants to merge 4 commits intomainfrom
feature/SPOC-322/delete-origin-log
Open

Add logging for origin changes on delete#383
mason-sharp wants to merge 4 commits intomainfrom
feature/SPOC-322/delete-origin-log

Conversation

@mason-sharp
Copy link
Member

DRAFT: currently uses from-v5_STABLE-part2 as a base to sequence PR order, will change to main later.

Report delete_origin_differs when a replicated DELETE targets a row whose local origin differs from the replication session origin. The new to be logged type shares the same early-return / GUC filtering logic as update_origin_differs (since_sub_creation, none, remote_only_differs).

  • spock_apply_heap.c: detect origin mismatch in the DELETE-found path
  • spock_conflict.c: extend same-origin guard to DELETE_ORIGIN_DIFFERS, add switch-case log message, remove stale placeholder comment
  • tests/regress/sql/tuple_origin.sql: add delete_origin_differs regression test
  • tests/tap/t/013_origin_change_restore.pl: add DELETE tests for all three log_origin_change modes

@mason-sharp mason-sharp requested a review from rasifr March 10, 2026 03:08
@mason-sharp mason-sharp added the in draft This PR created to test domething label Mar 10, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 72f8a948-8736-4133-a60b-a128ea63482c

📥 Commits

Reviewing files that changed from the base of the PR and between ea8b42a and 35b9f22.

📒 Files selected for processing (2)
  • src/spock_conflict.c
  • tests/tap/t/013_origin_change_restore.pl

📝 Walkthrough

Walkthrough

Adds logging for deletions when the local tuple origin differs, integrates that delete-origin-differs case into conflict reporting and logging, expands tests to cover delete-origin-change scenarios, and increases the TAP test timeout from 15 to 20 minutes.

Changes

Cohort / File(s) Summary
Apply logic
src/spock_apply_heap.c
Adds a branch that logs SPOCK_CT_DELETE_ORIGIN_DIFFERS when the local origin exists and differs from replorigin_session_origin before performing the delete as table owner.
Conflict reporting
src/spock_conflict.c
Integrates delete-origin-differs into spock_report_conflict mapping and logging, adds a dedicated switch case and refactors local-origin formatting in log messages.
Regression SQL tests
tests/regress/sql/tuple_origin.sql
Adds delete_origin_differs test sequence validating provider-side delete is applied on subscriber despite local-origin differences and that no resolution row is recorded.
TAP restore tests
tests/tap/t/013_origin_change_restore.pl
Expands seed data and adds Tests 5–8 to cover DELETE-origin-change scenarios (since_sub_creation, post-subscription delete, mode suppression, remote-only), and adjusts related expectations.
CI workflow
.github/workflows/spockbench.yml
Increases the "Run TAP tests" step timeout from 15 to 20 minutes (timeout-only change).

Poem

🐇
I hop through rows where origins roam,
I tag the trails that stray from home.
When deletes diverge, I leave a sign,
A tiny log, a tidy line.
Nibble, note, then onward I comb. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add logging for origin changes on delete' directly and clearly describes the main objective of the PR—adding logging for origin-change scenarios during DELETE operations.
Description check ✅ Passed The description is related to the changeset, providing context about the delete_origin_differs feature, explaining the rationale, and listing the specific files changed and their purposes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/SPOC-322/delete-origin-log

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mason-sharp
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/spock_conflict.c (1)

519-531: Consider including local tuple details in the log message for consistency with UPDATE_ORIGIN_DIFFERS.

The errdetail for DELETE_ORIGIN_DIFFERS only shows remote transaction info, but for origin-change debugging, the local tuple's origin and timestamp are valuable. The UPDATE_ORIGIN_DIFFERS case (lines 482-490) includes "existing local tuple {%s} xid=%u,origin=%s,timestamp=%s". Since localtup.data, local_tuple_xid, local_origin_str, and local_tup_ts_str are already populated, adding them would improve observability.

💡 Suggested enhancement to include local tuple info
 		case SPOCK_CT_DELETE_ORIGIN_DIFFERS:
 			ereport(spock_conflict_log_level,
-							   (errcode(ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION),
-								errmsg("CONFLICT: remote %s on relation %s replica identity index %s (origin differs). Resolution: %s.",
-											SpockConflictTypeNames[conflict_type],
-											qualrelname, idxname,
-											conflict_resolution_to_string(resolution)),
-								errdetail("tuple for remote delete in xact origin=%u,timestamp=%s,commit_lsn=%X/%X",
-											replorigin_session_origin,
-											timestamptz_to_str(replorigin_session_origin_timestamp),
-											(uint32) (replorigin_session_origin_lsn << 32),
-											(uint32) replorigin_session_origin_lsn)));
+					(errcode(ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION),
+					 errmsg("CONFLICT: remote %s on relation %s replica identity index %s (origin differs). Resolution: %s.",
+							SpockConflictTypeNames[conflict_type],
+							qualrelname, idxname,
+							conflict_resolution_to_string(resolution)),
+					 errdetail("existing local tuple {%s} xid=%u,origin=%s,timestamp=%s; remote delete in xact origin=%u,timestamp=%s,commit_lsn=%X/%X",
+							   localtup.data, local_tuple_xid,
+							   local_origin_str,
+							   local_tup_ts_str,
+							   replorigin_session_origin,
+							   timestamptz_to_str(replorigin_session_origin_timestamp),
+							   (uint32) (replorigin_session_origin_lsn << 32),
+							   (uint32) replorigin_session_origin_lsn)));
 			break;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/spock_conflict.c` around lines 519 - 531, The DELETE_ORIGIN_DIFFERS log
currently only emits remote transaction info; update the errdetail in the
SPOCK_CT_DELETE_ORIGIN_DIFFERS case to also include the local tuple details (use
localtup.data, local_tuple_xid, local_origin_str, local_tup_ts_str) similar to
the UPDATE_ORIGIN_DIFFERS handling so the message shows both existing local
tuple {…} xid=%u,origin=%s,timestamp=%s and the remote delete origin fields
(replorigin_session_origin, replorigin_session_origin_timestamp,
replorigin_session_origin_lsn) for consistent observability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/spock_conflict.c`:
- Around line 519-531: The DELETE_ORIGIN_DIFFERS log currently only emits remote
transaction info; update the errdetail in the SPOCK_CT_DELETE_ORIGIN_DIFFERS
case to also include the local tuple details (use localtup.data,
local_tuple_xid, local_origin_str, local_tup_ts_str) similar to the
UPDATE_ORIGIN_DIFFERS handling so the message shows both existing local tuple
{…} xid=%u,origin=%s,timestamp=%s and the remote delete origin fields
(replorigin_session_origin, replorigin_session_origin_timestamp,
replorigin_session_origin_lsn) for consistent observability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1b607150-038a-4fee-9ed3-c5ce975a0c7a

📥 Commits

Reviewing files that changed from the base of the PR and between 55434b3 and 7311e8d.

⛔ Files ignored due to path filters (1)
  • tests/regress/expected/tuple_origin.out is excluded by !**/*.out
📒 Files selected for processing (4)
  • src/spock_apply_heap.c
  • src/spock_conflict.c
  • tests/regress/sql/tuple_origin.sql
  • tests/tap/t/013_origin_change_restore.pl

@mason-sharp mason-sharp force-pushed the from-v5_STABLE-part2 branch from 55434b3 to 506481f Compare March 11, 2026 01:52
@rasifr rasifr force-pushed the from-v5_STABLE-part2 branch from 506481f to b220182 Compare March 11, 2026 10:53
Base automatically changed from from-v5_STABLE-part2 to main March 11, 2026 13:06
Report delete_origin_differs when a replicated DELETE targets a row
whose local origin differs from the replication session origin. The
new to be logged type shares the same early-return / GUC filtering logic
as update_origin_differs (since_sub_creation, none, remote_only_differs).

- spock_apply_heap.c: detect origin mismatch in the DELETE-found path
- spock_conflict.c: extend same-origin guard to DELETE_ORIGIN_DIFFERS,
  add switch-case log message, remove stale placeholder comment
- tests/regress/sql/tuple_origin.sql: add delete_origin_differs
  regression test
- tests/tap/t/013_origin_change_restore.pl: add DELETE tests for all
  three log_origin_change modes
@mason-sharp mason-sharp force-pushed the feature/SPOC-322/delete-origin-log branch from 7311e8d to 99a925b Compare March 11, 2026 16:25
@mason-sharp mason-sharp marked this pull request as ready for review March 11, 2026 16:52
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/tap/t/013_origin_change_restore.pl (1)

219-223: Clarify that Test 5 is the “origin unavailable” case, not the local-origin case.

The new comment describes the pg_restore row as InvalidRepOriginId, which reads the same as the later locally-written path. Rewording this will keep the test intent aligned with the runtime distinction between “local origin = 0” and “origin unavailable”.

✏️ Suggested wording
-# Row 4 was pg_restored to node 2 (predates subscription, origin = InvalidRepOriginId).
-# It has never been updated since, so its commit timestamp predates sub creation.
+# Row 4 was pg_restored to node 2 before the subscription existed.
+# This exercises the pre-existing-data / unavailable-origin path, not the
+# locally-written origin=0 path covered later.

Based on learnings: In the spock codebase, replication origin value 0 means the row was changed locally, while NULL / "unknown" is the distinct case where the local origin is genuinely unavailable (for example after pg_restore).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/tap/t/013_origin_change_restore.pl` around lines 219 - 223, Update the
comment for Test 5 to clarify it exercises the “origin unavailable” case (not
the local-origin case): replace the phrase "InvalidRepOriginId" with wording
such as "origin unavailable (NULL/unknown, e.g. pg_restore)" so the test intent
is clear that this row predates subscription and has no local origin (distinct
from local-origin = 0); keep the surrounding context mentioning Test 5 and the
ALTER SYSTEM setting spock.log_origin_change = 'since_sub_creation'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/tap/t/013_origin_change_restore.pl`:
- Around line 219-223: Update the comment for Test 5 to clarify it exercises the
“origin unavailable” case (not the local-origin case): replace the phrase
"InvalidRepOriginId" with wording such as "origin unavailable (NULL/unknown,
e.g. pg_restore)" so the test intent is clear that this row predates
subscription and has no local origin (distinct from local-origin = 0); keep the
surrounding context mentioning Test 5 and the ALTER SYSTEM setting
spock.log_origin_change = 'since_sub_creation'.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b71abf4-a821-400c-a930-70fb1c35eb2b

📥 Commits

Reviewing files that changed from the base of the PR and between 7311e8d and 76b79b2.

⛔ Files ignored due to path filters (1)
  • tests/regress/expected/tuple_origin.out is excluded by !**/*.out
📒 Files selected for processing (4)
  • src/spock_apply_heap.c
  • src/spock_conflict.c
  • tests/regress/sql/tuple_origin.sql
  • tests/tap/t/013_origin_change_restore.pl
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/spock_apply_heap.c

@mason-sharp mason-sharp removed the in draft This PR created to test domething label Mar 11, 2026
@mason-sharp mason-sharp force-pushed the feature/SPOC-322/delete-origin-log branch from a7c9d3b to 28f8b29 Compare March 11, 2026 18:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/spock_conflict.c`:
- Around line 521-536: The errdetail for case SPOCK_CT_DELETE_ORIGIN_DIFFERS
currently prints remotetup.data which can be NULL here; update the message to
use delete-shaped detail text by checking if remotetup is NULL and, if so,
render the delete key from oldkey (use oldkey.data) or else produce the "remote
delete in xact origin=...,timestamp=...,commit_lsn=..." form used by the other
DELETE branches; adjust the errdetail parameters (remotetup.data vs oldkey.data
and the origin/timestamp/LSN fields like replorigin_session_origin,
replorigin_session_origin_timestamp, replorigin_session_origin_lsn) so the
detail always prints a meaningful remote-delete description.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c8adeff-098f-42d9-9163-7512ef3eeece

📥 Commits

Reviewing files that changed from the base of the PR and between 76b79b2 and 28f8b29.

📒 Files selected for processing (3)
  • .github/workflows/spockbench.yml
  • src/spock_conflict.c
  • tests/tap/t/013_origin_change_restore.pl

We may want to examine moving some to weekly tests
@mason-sharp mason-sharp force-pushed the feature/SPOC-322/delete-origin-log branch from 28f8b29 to ea8b42a Compare March 11, 2026 19:04
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/spock_conflict.c`:
- Around line 354-355: The change added SPOCK_CT_DELETE_ORIGIN_DIFFERS to the
"ignore" path but spock_conflict_log_table() still NULLs local_origin when
local_tuple_origin == InvalidRepOriginId, collapsing the distinction between
"local change" (origin 0) and "unknown origin" (NULL). Update
spock_conflict_log_table() so that when constructing the
spock.resolutions.local_origin value you set it to the replication-local
sentinel (0) when local_tuple_origin == InvalidRepOriginId (or use the constant
representing local origin), and only write NULL when the origin is genuinely
unavailable; keep references to local_tuple_origin, local_origin,
InvalidRepOriginId and SPOCK_CT_DELETE_ORIGIN_DIFFERS to locate the logic to
change.
- Around line 528-535: Several errdetail calls in spock_conflict.c build a
commit_lsn using (uint32)(replorigin_session_origin_lsn << 32) which zeros the
high word; replace those manual bit-shift extracts with the canonical
LSN_FORMAT_ARGS macro. Locate each errdetail invocation in the conflict-handling
function that currently ends with
",commit_lsn=%X/%X",(uint32)(replorigin_session_origin_lsn << 32),(uint32)
replorigin_session_origin_lsn and change the format/arguments to use
LSN_FORMAT_ARGS(replorigin_session_origin_lsn) (i.e. keep the "%X/%X" in the
format string but remove the two uint32 casts and supply
LSN_FORMAT_ARGS(replorigin_session_origin_lsn) instead); do this for all five
occurrences referencing replorigin_session_origin_lsn (the same pattern appears
near the existing calls that also use timestamptz_to_str and errdetail).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 602a280a-3948-4070-8608-59ca5f76fff4

📥 Commits

Reviewing files that changed from the base of the PR and between 28f8b29 and ea8b42a.

📒 Files selected for processing (3)
  • .github/workflows/spockbench.yml
  • src/spock_conflict.c
  • tests/tap/t/013_origin_change_restore.pl
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/spockbench.yml

Use "local" for the origin when the row is local

Display 0 for local origin in log table
@mason-sharp mason-sharp force-pushed the feature/SPOC-322/delete-origin-log branch from ea8b42a to 35b9f22 Compare March 11, 2026 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant