Skip to content

Add origin and timestamp preservation to table repair.#73

Draft
ibrarahmad wants to merge 8 commits intopgEdge:mainfrom
ibrarahmad:PRESERVE-TIME-ORIGINID
Draft

Add origin and timestamp preservation to table repair.#73
ibrarahmad wants to merge 8 commits intopgEdge:mainfrom
ibrarahmad:PRESERVE-TIME-ORIGINID

Conversation

@ibrarahmad
Copy link
Contributor

This commit introduces logic to preserve replication origin metadata and commit timestamps during table repair operations. When enabled, repairs now maintain the original source node and timestamp information instead of marking repaired rows with current repair-time metadata.

The implementation extracts origin information from source row metadata and applies it during repair using PostgreSQL's replication origin API. Timestamp parsing supports multiple formats including RFC3339, PostgreSQL text format, and numeric Unix timestamps with automatic scale detection (seconds, milliseconds, microseconds, nanoseconds). Error handling ensures proper session cleanup and graceful degradation when origin metadata is unavailable.

Origin preservation works across repair modes including standard repair, fix-nulls updates, and bidirectional synchronization. New integration tests verify correct preservation of timestamps, origin node IDs, and row content integrity throughout the repair process.

This commit introduces logic to preserve replication origin metadata
and commit timestamps during table repair operations. When enabled,
repairs now maintain the original source node and timestamp information
instead of marking repaired rows with current repair-time metadata.

The implementation extracts origin information from source row metadata
and applies it during repair using PostgreSQL's replication origin API.
Timestamp parsing supports multiple formats including RFC3339, PostgreSQL
text format, and numeric Unix timestamps with automatic scale detection
(seconds, milliseconds, microseconds, nanoseconds). Error handling
ensures proper session cleanup and graceful degradation when origin
metadata is unavailable.

Origin preservation works across repair modes including standard repair,
fix-nulls updates, and bidirectional synchronization. New integration
tests verify correct preservation of timestamps, origin node IDs, and
row content integrity throughout the repair process.
@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request introduces replication origin preservation during table repairs. It adds database query functions for managing replication origins, extends the CLI and HTTP API with a preserve-origin option, implements origin-aware repair logic with per-row timestamp tracking, and includes comprehensive test coverage and documentation updates.

Changes

Cohort / File(s) Summary
Database Query Layer
db/queries/queries.go, db/queries/templates.go
Added six new public functions and corresponding SQL templates for replication origin management: GetReplicationOriginByName, CreateReplicationOrigin, SetupReplicationOriginSession, ResetReplicationOriginSession, SetupReplicationOriginXact, and ResetReplicationOriginXact. Enables querying and managing PostgreSQL replication origins.
CLI & HTTP API Integration
internal/cli/cli.go, internal/api/http/handler.go
Added preserve-origin boolean flag to table-repair command and wired it through the repair task; added corresponding field to HTTP request body for the table-repair endpoint.
Core Repair Logic
internal/consistency/repair/table_repair.go
Implemented origin-aware repair execution with grouping utilities, LSN resolution, per-origin transaction setup, session management, and cleanup. Added PreserveOrigin feature flag, setupTransactionMode, and numerous helper methods for extracting and applying origin metadata during updates and upserts.
Test Infrastructure
internal/consistency/repair/table_repair_batch_test.go, tests/integration/helpers_test.go
Added batch test file for origin key generation, grouping, and timestamp handling; added test helpers: getCommitTimestamp, getReplicationOrigin, compareTimestamps, and compareTimestampsExact.
Integration Tests
tests/integration/table_repair_test.go, tests/integration/timestamp_comparison_test.go, tests/integration/crash_recovery_test.go
Added four new table-repair test scenarios covering bidirectional updates and origin preservation; added timestamp comparison validation tests; modified crash recovery test to disable preserve-origin when origin node is unavailable.
Documentation
docs/api.md, docs/commands/repair/table-repair.md, docs/http-api.md
Added preserve-origin flag documentation to API reference, expanded table-repair command documentation with feature section, and documented preserve_origin field in HTTP API with microsecond-precision timestamp details.
Miscellaneous
go.mod, pkg/logger/logger.go
Updated go-sqlite3 dependency from v1.14.22 to v1.14.33; added SetOutput function to logger package for redirecting log output.

Poem

🐰 With whiskers twitching, we now preserve,
The origin's LSN we serve,
Each row's timestamp, precise to the task,
Repair with ancestry—that's all we ask! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main feature added: preservation of origin and timestamp data during table repair operations.
Description check ✅ Passed The description is directly related to the changeset, explaining the feature implementation, timestamp parsing support, error handling, and integration test coverage.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@ibrarahmad
Copy link
Contributor Author

For detailed refence see PR

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: 4

🤖 Fix all issues with AI agents
In `@db/queries/templates.go`:
- Around line 1552-1569: Add a brief comment above the replication origin SQL
templates (near GetReplicationOriginByName, CreateReplicationOrigin,
SetupReplicationOriginSession, ResetReplicationOriginSession,
SetupReplicationOriginXact, ResetReplicationOriginXact) stating that the
pg_replication_origin_* functions require PostgreSQL 9.5 or newer and that
calling them typically requires superuser or equivalent replication/owner
privileges; also add a short note to the README or database setup docs
documenting the minimum PostgreSQL version (>=9.5) and the privilege
requirements for these functions.

In `@internal/consistency/repair/table_repair_batch_test.go`:
- Around line 217-224: The comment for TestParseNumericTimestamp incorrectly
states that Unix seconds value 1704067200 corresponds to 2024-01-01 12:00:00
UTC; update the comment to the correct timestamp (2024-01-01 00:00:00 UTC) so it
accurately documents the expected value used in the sec variable and
parseNumericTimestamp test; locate the comment in TestParseNumericTimestamp near
the sec := time.Unix(1704067200, 0) line and change the annotation only.

In `@internal/consistency/repair/table_repair.go`:
- Around line 2736-2750: The code in resolveOriginLSN (the block that picks
survivorNode using t.Pools and t.SourceOfTruth and currently returns fmt.Errorf
when none found) should not hard-fail; instead log or warn and return (nil,
false, nil) to allow repairs to continue in degraded preserve-origin mode.
Change the branch that checks survivorNode == "" so it emits a warning
mentioning batchKey.nodeOrigin (use the existing logger or
fmt.Printf/processLogger) and then returns nil, false, nil rather than an error;
keep the survivor selection logic using t.Pools and t.SourceOfTruth unchanged.
- Around line 2301-2343: The current loop in executeUpserts processes multiple
originGroups in a single transaction so pg_replication_origin_xact_setup() is
overwritten and all rows get the last batch's origin; fix by ensuring each
origin group runs in its own transaction or by resetting the origin xact before
re-setting it: update executeUpserts (referencing executeUpsertBatch,
task.setupOriginForBatchKey, task.resetReplicationOriginXact,
task.resetReplicationOriginSession) to either (A) begin a fresh transaction for
each batchKey, call task.setupOriginForBatchKey, run executeUpsertBatch, commit
that transaction and then reset session as needed, or (B) if keeping one outer
tx, call task.resetReplicationOriginXact() (and handle errors) before calling
task.setupOriginForBatchKey for the next batch so per-batch origin
timestamps/LSNs are preserved.
🧹 Nitpick comments (1)
pkg/logger/logger.go (1)

31-33: *Accept io.Writer instead of os.File in SetOutput.

The underlying Log.SetOutput accepts io.Writer. Restricting the wrapper to *os.File is unnecessarily limiting and goes against Go best practices of accepting interfaces, not concrete types. Since *os.File implements io.Writer, this change is fully backward compatible while enabling greater flexibility for testing and custom output destinations.

♻️ Proposed refactor
 import (
 	"fmt"
+	"io"
 	"os"

 	"github.com/charmbracelet/log"
 )
@@
-func SetOutput(w *os.File) {
+func SetOutput(w io.Writer) {
 	Log.SetOutput(w)
 }

@mason-sharp mason-sharp marked this pull request as draft February 12, 2026 00:28
mason-sharp and others added 3 commits February 15, 2026 19:46
Three bugs prevented preserve-origin from working end-to-end:

1. GetSpockOriginLSNForNode used a broken LIKE pattern that never matched
   actual spock origin names. Replaced with JOINs through spock.subscription
   and spock.node, matching the approach used by GetSpockSlotLSNForNode.

2. executeUpserts called resetReplicationOriginSession before tx.Commit(),
   clearing the origin from the WAL commit record (roident=0).

3. pg_replication_origin_xact_setup is per-transaction, so all rows in a
   single transaction received the same timestamp. Added
   executePreserveOriginUpserts which uses a dedicated connection and
   separate transactions per (origin, timestamp) batch key, preserving
   per-row timestamps.

When PreserveOrigin is active, deletes now commit in a separate transaction
before the per-batch-key upsert transactions. The standard (non-preserve)
path is unchanged.

Also adds TestTableRepair_MixedOps_PreserveOrigin integration test covering
DELETE+INSERT+UPDATE with origin/timestamp verification, and fixes the
getReplicationOrigin test helper to use spock.xact_commit_timestamp_origin.
@ibrarahmad ibrarahmad force-pushed the PRESERVE-TIME-ORIGINID branch 4 times, most recently from 760495d to cca05e9 Compare February 17, 2026 15:00
Skip FixNulls test (UPDATE doesn't preserve origin). Fix Bidirectional
test (proper transaction isolation for divergence creation).
@ibrarahmad ibrarahmad force-pushed the PRESERVE-TIME-ORIGINID branch from cca05e9 to 5596050 Compare February 17, 2026 15:00
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":401,"request":{"method":"PATCH","url":"https://api.github.com/repos/pgEdge/ace/issues/comments/3884267086","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: skip review by coderabbit.ai -->\n\n> [!IMPORTANT]\n> ## Review skipped\n> \n> Draft detected.\n> \n> Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command.\n> \n> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.\n> \n> Use the checkbox below for a quick retry:\n> - [ ] <!-- {\"checkboxId\": \"e9bb8d72-00e8-4f67-9cb2-caf3b22574fe\"} --> 🔍 Trigger review\n\n<!-- end of auto-generated comment: skip review by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nThis pull request introduces replication origin preservation during table repairs. It adds database query functions for managing replication origins, extends the CLI and HTTP API with a preserve-origin option, implements origin-aware repair logic with per-row timestamp tracking, and includes comprehensive test coverage and documentation updates.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Database Query Layer** <br> `db/queries/queries.go`, `db/queries/templates.go`|Added six new public functions and corresponding SQL templates for replication origin management: GetReplicationOriginByName, CreateReplicationOrigin, SetupReplicationOriginSession, ResetReplicationOriginSession, SetupReplicationOriginXact, and ResetReplicationOriginXact. Enables querying and managing PostgreSQL replication origins.|\n|**CLI & HTTP API Integration** <br> `internal/cli/cli.go`, `internal/api/http/handler.go`|Added preserve-origin boolean flag to table-repair command and wired it through the repair task; added corresponding field to HTTP request body for the table-repair endpoint.|\n|**Core Repair Logic** <br> `internal/consistency/repair/table_repair.go`|Implemented origin-aware repair execution with grouping utilities, LSN resolution, per-origin transaction setup, session management, and cleanup. Added PreserveOrigin feature flag, setupTransactionMode, and numerous helper methods for extracting and applying origin metadata during updates and upserts.|\n|**Test Infrastructure** <br> `internal/consistency/repair/table_repair_batch_test.go`, `tests/integration/helpers_test.go`|Added batch test file for origin key generation, grouping, and timestamp handling; added test helpers: getCommitTimestamp, getReplicationOrigin, compareTimestamps, and compareTimestampsExact.|\n|**Integration Tests** <br> `tests/integration/table_repair_test.go`, `tests/integration/timestamp_comparison_test.go`, `tests/integration/crash_recovery_test.go`|Added four new table-repair test scenarios covering bidirectional updates and origin preservation; added timestamp comparison validation tests; modified crash recovery test to disable preserve-origin when origin node is unavailable.|\n|**Documentation** <br> `docs/api.md`, `docs/commands/repair/table-repair.md`, `docs/http-api.md`|Added preserve-origin flag documentation to API reference, expanded table-repair command documentation with feature section, and documented preserve_origin field in HTTP API with microsecond-precision timestamp details.|\n|**Miscellaneous** <br> `go.mod`, `pkg/logger/logger.go`|Updated go-sqlite3 dependency from v1.14.22 to v1.14.33; added SetOutput function to logger package for redirecting log output.|\n\n## Poem\n\n> 🐰 With whiskers twitching, we now preserve,  \n> The origin's LSN we serve,  \n> Each row's timestamp, precise to the task,  \n> Repair with ancestry—that's all we ask! ✨\n\n</details>\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n<details>\n<summary>❌ Failed checks (1 warning)</summary>\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n</details>\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                            |\n| :---------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|    Title check    | ✅ Passed | The title accurately and concisely summarizes the main feature added: preservation of origin and timestamp data during table repair operations.                        |\n| Description check | ✅ Passed | The description is directly related to the changeset, explaining the feature implementation, timestamp parsing support, error handling, and integration test coverage. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=pgEdge/ace&utm_content=73)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":1}},"response":{"url":"https://api.github.com/repos/pgEdge/ace/issues/comments/3884267086","status":401,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","connection":"close","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Tue, 17 Feb 2026 15:02:20 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-media-type":"github.v3; format=json","x-github-request-id":"4102:2B631F:137C83:53D93B:699482FA","x-xss-protection":"0"},"data":{"message":"Bad credentials","documentation_url":"https://docs.github.com/rest","status":"401"}}}

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.

2 participants

Comments