Skip to content

Commit 45d9921

Browse files
authored
classify postgres slot allocation issue (#3320)
1 parent 7dee54f commit 45d9921

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

flow/alerting/classifier.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ var (
157157
// These are unclassified and should not be exposed
158158
Class: "OTHER", action: NotifyTelemetry,
159159
}
160+
// Postgres 16.9/17.5 etc. introduced a bug where certain workloads can cause logical replication to
161+
// request a memory allocation of >1GB, which is not allowed by Postgres. Fixed already, but we need to handle this error
162+
// https://github.com/postgres/postgres/commit/d87d07b7ad3b782cb74566cd771ecdb2823adf6a
163+
ErrorPostgresSlotMemalloc = ErrorClass{
164+
Class: "ERROR_POSTGRES_SLOT_MEMALLOC", action: NotifyUser,
165+
}
160166
)
161167

162168
func (e ErrorClass) String() string {
@@ -322,6 +328,10 @@ func GetErrorClass(ctx context.Context, err error) (ErrorClass, ErrorInfo) {
322328
return ErrorNotifyConnectivity, pgErrorInfo
323329
}
324330

331+
if strings.Contains(pgErr.Message, "invalid memory alloc request size") {
332+
return ErrorPostgresSlotMemalloc, pgErrorInfo
333+
}
334+
325335
// Fall through for other internal errors
326336
return ErrorOther, pgErrorInfo
327337

flow/alerting/classifier_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,39 @@ func TestAuroraInternalWALErrorShouldBeRecoverable(t *testing.T) {
134134
}, errInfo, "Unexpected error info")
135135
}
136136

137+
func TestNeonProjectQuotaExceededErrorShouldBeConnectivity(t *testing.T) {
138+
// Simulate a Neon project quota exceeded error
139+
err := &pgconn.PgError{
140+
Severity: "ERROR",
141+
Code: pgerrcode.InternalError,
142+
Message: "Your account or project has exceeded the compute time quota. Upgrade your plan to increase limits.",
143+
}
144+
errorClass, errInfo := GetErrorClass(t.Context(),
145+
exceptions.NewPeerCreateError(fmt.Errorf("failed to create connection: failed to connect to `<user, host>: server error: `: %w", err)))
146+
assert.Equal(t, ErrorNotifyConnectivity, errorClass, "Unexpected error class")
147+
assert.Equal(t, ErrorInfo{
148+
Source: ErrorSourcePostgres,
149+
Code: pgerrcode.InternalError,
150+
}, errInfo, "Unexpected error info")
151+
}
152+
153+
func TestPostgresMemoryAllocErrorShouldBeSlotMemalloc(t *testing.T) {
154+
// Simulate a Postgres memory allocation error
155+
err := &exceptions.PostgresWalError{
156+
Msg: &pgproto3.ErrorResponse{
157+
Severity: "ERROR",
158+
Code: pgerrcode.InternalError,
159+
Message: "invalid memory alloc request size 1073741824",
160+
},
161+
}
162+
errorClass, errInfo := GetErrorClass(t.Context(), fmt.Errorf("error in WAL: %w", err))
163+
assert.Equal(t, ErrorPostgresSlotMemalloc, errorClass, "Unexpected error class")
164+
assert.Equal(t, ErrorInfo{
165+
Source: ErrorSourcePostgres,
166+
Code: pgerrcode.InternalError,
167+
}, errInfo, "Unexpected error info")
168+
}
169+
137170
func TestClickHouseAccessEntityNotFoundErrorShouldBeRecoverable(t *testing.T) {
138171
// Simulate a ClickHouse access entity not found error
139172
for idx, msg := range []string{

0 commit comments

Comments
 (0)