MCPcopy Create free account
hub / github.com/Permify/permify / Repair

Method Repair

pkg/database/postgres/repair.go:45–110  ·  view source on GitHub ↗

Repair performs XID counter repair to prevent XID wraparound issues This function uses a safe approach: only advance XID counter, don't modify existing data

(ctx context.Context, config *RepairConfig)

Source from the content-addressed store, hash-verified

43// Repair performs XID counter repair to prevent XID wraparound issues
44// This function uses a safe approach: only advance XID counter, don't modify existing data
45func (p *Postgres) Repair(ctx context.Context, config *RepairConfig) (*RepairResult, error) {
46 if config == nil {
47 config = DefaultRepairConfig()
48 }
49
50 // Validate BatchSize - don't accept 0 or negative values
51 if config.BatchSize <= 0 {
52 config.BatchSize = 1000 // Use default value
53 slog.InfoContext(ctx, "Invalid BatchSize provided, using default", slog.Int("default_batch_size", 1000))
54 }
55
56 result := &RepairResult{
57 Errors: make([]error, 0),
58 }
59
60 slog.InfoContext(ctx, "Starting PostgreSQL transaction ID counter repair",
61 slog.Bool("dry_run", config.DryRun),
62 slog.Int("batch_size", config.BatchSize))
63
64 // Step 1: Get current PostgreSQL XID
65 currentXID, err := p.getCurrentPostgreXID(ctx)
66 if err != nil {
67 return result, fmt.Errorf("failed to get current PostgreSQL XID: %w", err)
68 }
69
70 if config.Verbose {
71 slog.InfoContext(ctx, "Current PostgreSQL transaction ID", slog.Uint64("current_xid", currentXID))
72 }
73
74 // Step 2: Get maximum referenced XID from transactions table
75 maxReferencedXID, err := p.getMaxReferencedXID(ctx)
76 if err != nil {
77 result.Errors = append(result.Errors, fmt.Errorf("failed to get max referenced XID: %w", err))
78 return result, nil
79 }
80
81 if config.Verbose {
82 slog.InfoContext(ctx, "Maximum referenced transaction ID", slog.Uint64("max_referenced_xid", maxReferencedXID))
83 }
84
85 // Step 3: Advance XID counter if needed
86 if maxReferencedXID > currentXID {
87 counterDelta := int(maxReferencedXID - currentXID + 1000) // Add safety buffer
88
89 if config.DryRun {
90 slog.InfoContext(ctx, "Would advance XID counter",
91 slog.Int("counter_delta", counterDelta),
92 slog.Uint64("target_xid", maxReferencedXID+1000))
93 result.CreatedTxIdFixed = counterDelta
94 } else {
95 if err := p.advanceXIDCounterByDelta(ctx, counterDelta, config); err != nil {
96 result.Errors = append(result.Errors, fmt.Errorf("failed to advance XID counter: %w", err))
97 } else {
98 result.CreatedTxIdFixed = counterDelta
99 }
100 }
101 } else {
102 slog.InfoContext(ctx, "No XID counter advancement needed")

Callers 2

repair_test.goFile · 0.80
repairDatastoreFunction · 0.80

Calls 4

getCurrentPostgreXIDMethod · 0.95
getMaxReferencedXIDMethod · 0.95
DefaultRepairConfigFunction · 0.85

Tested by

no test coverage detected