-
Notifications
You must be signed in to change notification settings - Fork 58
Description
While creating 70 instances concurrently using the same Terraform plan I used many times before without any problem, I'm now hitting a number of 500 errors in every run consistently. The errors in nexus log all look like the one below:
02:12:24.115Z INFO 65a11c18-7f59-41ac-b9e7-680627f996e7 (dropshot_external): request completed
error_message_external = Internal Server Error
error_message_internal = saga ACTION error at node "output": unexpected database error: root: memory budget exceeded: 7854088 bytes requested, 127439909 currently allocated, 134217728 bytes in budget
file = /home/build/.cargo/git/checkouts/dropshot-a4a923d29dccc492/0cd0e82/dropshot/src/server.rs:866
latency_us = 1918719
local_addr = 172.30.2.5:443
method = POST
remote_addr = 172.20.17.42:54427
req_id = 9c1272f5-2184-4f5b-b7c9-5b6b43adad1c
response_code = 500
uri = https://oxide.sys.rack2.eng.oxide.computer/v1/instances?project=fe0da422-5c48-4b52-8010-f2fc401f090f
Using this D script against the nexus process running in sled 8, I was able to capture the database error in question:
conn_id: f2bdf557-5a71-4a0f-9a98-83a50a11f1cd, latency: 2329 us, query: 'INSERT INTO "saga_node_event" ("saga_id", "node_id", "event_type", "data", "event_time", "creator") VALUES ($1, $2, $3, $4, $5, $6) -- binds: [SagaId(9225d6c7-6369-40fa-b9cf-e3b698434a66), SagaNodeId(5), "failed", Object {"ActionFailed": Object {"source_error": Object {"InternalError": Object {"internal_message": String("unexpected database error: root: memory budget exceeded: 7854088 bytes requested, 133920542 currently allocated, 134217728 bytes in budget")}}}}, 2024-06-15T04:17:54.044368305Z, 65a11c18-7f59-41ac-b9e7-680627f996e7]'
It is however an insert statement and didn't appear to be the culprit. I had a look at 3 different occurrences of the 500 errors and tried to pinpoint the more expensive queries running around the same time. Here is one of those (latency = 346542 us):
WITH found_row AS MATERIALIZED (
SELECT
"vpc_subnet"."id",
"vpc_subnet"."name",
"vpc_subnet"."description",
"vpc_subnet"."time_created",
"vpc_subnet"."time_modified",
"vpc_subnet"."time_deleted",
"vpc_subnet"."vpc_id",
"vpc_subnet"."rcgen",
"vpc_subnet"."ipv4_block",
"vpc_subnet"."ipv6_block"
FROM
"vpc_subnet"
WHERE
(
("vpc_subnet"."id" = $1)
AND (
"vpc_subnet"."time_deleted" IS NULL
)
) FOR
UPDATE
),
dummy AS MATERIALIZED (
SELECT
IF(
EXISTS(
SELECT
"id"
FROM
found_row
),
TRUE,
CAST(1 / 0 AS BOOL)
)
),
updated_row AS MATERIALIZED (
UPDATE
"vpc_subnet"
SET
"rcgen" = "rcgen" + 1
WHERE
"id" IN (
SELECT
"id"
FROM
found_row
) RETURNING 1
),
inserted_row AS (
INSERT INTO "network_interface" (
"id", "name", "description", "time_created",
"time_modified", "time_deleted",
"kind", "parent_id", "vpc_id", "subnet_id",
"mac", "ip", "slot", "is_primary"
) WITH validated_interface(
"vpc_id", "subnet_id", "parent_id",
"slot", "is_primary"
) AS (
SELECT
CAST(
IF(
COALESCE(
(
SELECT
"vpc_id"
FROM
"network_interface"
WHERE
"time_deleted" IS NULL
AND "parent_id" = $2
AND "kind" = $3
LIMIT
1
), $4
) = $5,
$6,
'multiple-vpcs'
) AS UUID
) AS "vpc_id",
CAST(
IF(
EXISTS(
SELECT
"subnet_id"
FROM
"network_interface"
WHERE
"id" != $7
AND "parent_id" = $8
AND "kind" = $9
AND "time_deleted" IS NULL
AND "subnet_id" = $10
),
'non-unique-subnets',
$11
) AS UUID
) AS "subnet_id",
(
CAST(
CASE COALESCE(
(
SELECT
CASE WHEN "active_propolis_id" IS NULL THEN "state" ELSE $12 END
FROM
"instance"
WHERE
"id" = $13
AND "time_deleted" IS NULL
),
$14
) WHEN $15 THEN $16 WHEN $17 THEN $18 WHEN $19 THEN $20 ELSE $21 END AS UUID
)
),
(
SELECT
COALESCE(
(
SELECT
$22 + "shift" AS "slot"
FROM
(
SELECT
generate_series(0, $23) AS "index",
generate_series(0, $24) AS "shift"
UNION ALL
SELECT
generate_series($25, $26) AS "index",
generate_series($27, -1) AS "shift"
)
LEFT OUTER JOIN "network_interface" ON (
"parent_id", "slot", "time_deleted" IS NULL
) = ($28, $29 + "shift", TRUE)
WHERE
"slot" IS NULL
ORDER BY
"index"
LIMIT
1
), 0
)
),
(
SELECT
NOT EXISTS(
SELECT
1
FROM
"network_interface"
WHERE
"parent_id" = $30
AND "kind" = $31
AND "time_deleted" IS NULL
LIMIT
1
)
)
)
SELECT
$32 AS "id",
$33 AS "name",
$34 AS "description",
$35 AS "time_created",
$36 AS "time_modified",
$37 AS "time_deleted",
$38 AS "kind",
$39 AS "parent_id",
(
SELECT
"vpc_id"
FROM
validated_interface
),
(
SELECT
"subnet_id"
FROM
validated_interface
),
(
SELECT
$40 + "shift" AS "mac"
FROM
(
SELECT
generate_series(0, $41) AS "index",
generate_series(0, $42) AS "shift"
UNION ALL
SELECT
generate_series($43, $44) AS "index",
generate_series($45, -1) AS "shift"
)
LEFT OUTER JOIN "network_interface" ON (
"vpc_id", "mac", "time_deleted" IS NULL
) = ($46, $47 + "shift", TRUE)
WHERE
"mac" IS NULL
ORDER BY
"index"
LIMIT
1
) AS "mac",
(
SELECT
$48 + "shift" AS "ip"
FROM
(
SELECT
generate_series(0, $49) AS "index",
generate_series(0, $50) AS "shift"
UNION ALL
SELECT
generate_series($51, $52) AS "index",
generate_series($53, -1) AS "shift"
)
LEFT OUTER JOIN "network_interface" ON (
"subnet_id", "ip", "time_deleted" IS NULL
) = ($54, $55 + "shift", TRUE)
WHERE
"ip" IS NULL
ORDER BY
"index"
LIMIT
1
) AS "ip",
(
SELECT
"slot"
FROM
validated_interface
),
(
SELECT
"is_primary"
FROM
validated_interface
) RETURNING "network_interface"."id",
"network_interface"."name",
"network_interface"."description",
"network_interface"."time_created",
"network_interface"."time_modified",
"network_interface"."time_deleted",
"network_interface"."kind",
"network_interface"."parent_id",
"network_interface"."vpc_id",
"network_interface"."subnet_id",
"network_interface"."mac",
"network_interface"."ip",
"network_interface"."slot",
"network_interface"."is_primary"
)
SELECT
*
FROM
inserted_row -- binds: [7612ed87-eff5-433f-b781-cf4cbeb75def, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, Instance, 91a91cab-2fbd-4c1e-a91f-4f2bcae5705b, 91a91cab-2fbd-4c1e-a91f-4f2bcae5705b, "91a91cab-2fbd-4c1e-a91f-4f2bcae5705b", f0c3f7b4-3190-43d8-b695-3ac56b995077, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, Instance, 7612ed87-eff5-433f-b781-cf4cbeb75def, "7612ed87-eff5-433f-b781-cf4cbeb75def", Vmm, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, Destroyed, NoVmm, "aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b", Creating, "aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b", Destroyed, "no-instance", "bad-state", 0, 8, 8, 9, 8, 0, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, 0, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, Instance, f0c3f7b4-3190-43d8-b695-3ac56b995077, Name(Name("net0")), "net0", 2024-06-15T04:17:53.697381777Z, 2024-06-15T04:17:53.697381777Z, None, Instance, aa47bc6e-e1b9-4b3a-baa0-83f6e4b06c2b, MacAddr(MacAddr(MacAddr6([168, 64, 37, 248, 102, 112]))), 432527, 432527, 432528, 983039, -550512, 91a91cab-2fbd-4c1e-a91f-4f2bcae5705b, MacAddr(MacAddr(MacAddr6([168, 64, 37, 248, 102, 112]))), V4(Ipv4Network { addr: 192.168.128.5, prefix: 32 }), 249, 249, 250, 249, 0, 7612ed87-eff5-433f-b781-cf4cbeb75def, V4(Ipv4Network { addr: 192.168.128.5, prefix: 32 })]
(a grep of this query pattern shows the latency was as high as 1523657 us during the window when I was running terraform apply
and tracing the database queries).
The complete nexus log and db query tracing output are located in catacomb:/staff/dogfood/omicron-5904.