MCPcopy Create free account
hub / github.com/PostHog/duckgres / RefreshS3Secret

Function RefreshS3Secret

server/server.go:2029–2071  ·  view source on GitHub ↗

RefreshS3Secret replaces the DuckDB S3 secret with updated credentials. Used when a hot-idle worker is reclaimed and STS credentials have rotated. Respects the configured S3 provider (config, aws_sdk, credential_chain).

(db *sql.DB, dlCfg DuckLakeConfig, duckLakeSem chan struct{})

Source from the content-addressed store, hash-verified

2027 stmt: "CREATE INDEX IF NOT EXISTS idx_ducklake_schema_versions_tbl_schema_version ON ducklake_schema_versions (table_id, schema_version)",
2028 },
2029}
2030
2031// ensureDuckLakeMetadataIndexes connects directly to the DuckLake PostgreSQL
2032// metadata store and creates indexes that dramatically improve query planning
2033// performance. This is non-fatal — if it fails, DuckLake still works, just slower.
2034// Retries on subsequent AttachDuckLake calls until it succeeds.
2035func ensureDuckLakeMetadataIndexes(dlCfg DuckLakeConfig) {
2036 if duckLakeIndexDone.Load() {
2037 return
2038 }
2039
2040 // Only relevant for PostgreSQL metadata stores.
2041 if !strings.HasPrefix(dlCfg.MetadataStore, "postgres:") {
2042 return
2043 }
2044
2045 // Serialize concurrent attempts (multiple connections attaching simultaneously).
2046 duckLakeIndexMu.Lock()
2047 defer duckLakeIndexMu.Unlock()
2048
2049 // Double-check after acquiring the lock.
2050 if duckLakeIndexDone.Load() {
2051 return
2052 }
2053
2054 // Strip the "postgres:" DuckLake protocol prefix to get a standard libpq connection string.
2055 connStr := strings.TrimPrefix(dlCfg.MetadataStore, "postgres:")
2056
2057 // pgx/stdlib accepts libpq key=value format directly.
2058 pgDB, err := sql.Open("pgx", connStr)
2059 if err != nil {
2060 slog.Warn("Failed to open connection for DuckLake metadata indexes.", "error", err)
2061 return
2062 }
2063 defer func() { _ = pgDB.Close() }()
2064
2065 // Fast path: a single pg_indexes lookup avoids 9 CREATE INDEX round-trips
2066 // when all expected indexes already exist. Each CREATE INDEX IF NOT EXISTS
2067 // is a no-op at the storage layer but still costs a server round-trip; under
2068 // pgbouncer transaction pooling that round-trip can take 1-2s during burst
2069 // load (server-conn handover + TLS handshake to RDS). Collapsing the check
2070 // to one round-trip cuts the post-attach window from ~16s to a few hundred
2071 // ms in the steady state.
2072 expectedNames := make([]string, len(duckLakeMetadataIndexes))
2073 for i, ix := range duckLakeMetadataIndexes {
2074 expectedNames[i] = ix.name

Callers 1

runRotationScenarioFunction · 0.92

Calls 8

newAttachStepExecerFunction · 0.85
S3ProviderForConfigFunction · 0.85
buildAWSSdkSecretFunction · 0.85
buildConfigSecretFunction · 0.85
releaseSemMethod · 0.80
isTransactionAbortedFunction · 0.70
ExecMethod · 0.65

Tested by 1

runRotationScenarioFunction · 0.74