mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-07 13:32:57 +00:00
1426 lines
40 KiB
YAML
1426 lines
40 KiB
YAML
openapi: "3.0.2"
|
|
info:
|
|
title: Page Server API
|
|
description: Neon Pageserver API
|
|
version: "1.0"
|
|
license:
|
|
name: "Apache"
|
|
url: https://github.com/neondatabase/neon/blob/main/LICENSE
|
|
servers:
|
|
- url: ""
|
|
paths:
|
|
/v1/status:
|
|
description: Healthcheck endpoint
|
|
get:
|
|
description: Healthcheck
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- id
|
|
properties:
|
|
id:
|
|
type: integer
|
|
|
|
/v1/disk_usage_eviction/run:
|
|
put:
|
|
description: Do an iteration of disk-usage-based eviction to evict a given amount of disk space.
|
|
security: []
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- evict_bytes
|
|
properties:
|
|
evict_bytes:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: |
|
|
The run completed.
|
|
This does not necessarily mean that we actually evicted `evict_bytes`.
|
|
Examine the returned object for detail, or, just watch the actual effect of the call using `du` or `df`.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
|
|
/v1/reload_auth_validation_keys:
|
|
post:
|
|
description: Reloads the JWT public keys from their pre-configured location on disk.
|
|
responses:
|
|
"200":
|
|
description: The reload completed successfully.
|
|
|
|
/v1/tenant/{tenant_id}:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
get:
|
|
description: Get tenant status
|
|
responses:
|
|
"200":
|
|
description: Currently returns the flag whether the tenant has inprogress timeline downloads
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantInfo"
|
|
|
|
delete:
|
|
description: |
|
|
Attempts to delete specified tenant. 500, 503 and 409 errors should be retried. Deleting
|
|
a non-existent tenant is considered successful (returns 200).
|
|
responses:
|
|
"200":
|
|
description: Tenant was successfully deleted, or was already not found.
|
|
"503":
|
|
description: Service is unavailable, or tenant is already being modified (perhaps concurrently deleted)
|
|
|
|
|
|
/v1/tenant/{tenant_id}/time_travel_remote_storage:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: travel_to
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
- name: done_if_after
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
put:
|
|
description: Time travel the tenant's remote storage
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
|
|
/v1/tenant/{tenant_id}/timeline/{timeline_id}:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
get:
|
|
description: Get info about the timeline
|
|
responses:
|
|
"200":
|
|
description: TimelineInfo
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TimelineInfo"
|
|
|
|
delete:
|
|
description: "Attempts to delete specified timeline. 500 and 409 errors should be retried"
|
|
responses:
|
|
"404":
|
|
description: Timeline not found. This is the success path.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/NotFoundError"
|
|
"409":
|
|
description: Deletion is already in progress, continue polling
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
"412":
|
|
description: Tenant is missing, or timeline has children
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PreconditionFailedError"
|
|
|
|
/v1/tenant/{tenant_id}/timeline/{timeline_id}/get_timestamp_of_lsn:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
get:
|
|
description: Get timestamp for a given LSN
|
|
parameters:
|
|
- name: lsn
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
description: A LSN to get the timestamp
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
"412":
|
|
description: No timestamp is found for given LSN, e.g. if there had been no commits till LSN
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PreconditionFailedError"
|
|
|
|
/v1/tenant/{tenant_id}/timeline/{timeline_id}/get_lsn_by_timestamp:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
get:
|
|
description: Get LSN by a timestamp
|
|
parameters:
|
|
- name: timestamp
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
description: A timestamp to get the LSN
|
|
- name: with_lease
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: boolean
|
|
description: Whether to grant a lease to the corresponding LSN. Default to false.
|
|
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LsnByTimestampResponse"
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/lsn_lease:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
post:
|
|
description: Obtains a lease for the given LSN.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- lsn
|
|
properties:
|
|
lsn:
|
|
description: A LSN to obtain the lease for.
|
|
type: string
|
|
format: hex
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LsnLease"
|
|
|
|
/v1/tenant/{tenant_id}/timeline/{timeline_id}/do_gc:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
put:
|
|
description: Garbage collect given timeline
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/block_gc:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
post:
|
|
description: Persistently add a gc blocking at the tenant level because of this timeline
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/unblock_gc:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
post:
|
|
description: Persistently remove a tenant level gc blocking for this timeline
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/mark_invisible:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: hex
|
|
put:
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
is_visible:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
|
|
/v1/tenant/{tenant_shard_id}/location_config:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: flush_ms
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
- name: lazy
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: boolean
|
|
description: Set to true for attaches to queue up until activated by compute. Eager (false) is the default.
|
|
put:
|
|
description: |
|
|
Configures a _tenant location_, that is how a particular pageserver handles
|
|
a particular tenant. This includes _attached_ tenants, i.e. those ingesting WAL
|
|
and page service requests, and _secondary_ tenants, i.e. those which are just keeping
|
|
a warm cache in anticipation of transitioning to attached state in the future.
|
|
|
|
This is a declarative, idempotent API: there are not separate endpoints
|
|
for different tenant location configurations. Rather, this single endpoint accepts
|
|
a description of the desired location configuration, and makes whatever changes
|
|
are required to reach that state.
|
|
|
|
In imperative terms, this API is used to attach and detach tenants, and
|
|
to transition tenants to and from secondary mode.
|
|
|
|
This is a synchronous API: there is no 202 response. State transitions should always
|
|
be fast (milliseconds), with the exception of requests setting `flush_ms`, in which case
|
|
the caller controls the runtime of the request.
|
|
|
|
In some state transitions, it makes sense to flush dirty data to remote storage: this includes transitions
|
|
to AttachedStale and Detached. Flushing is never necessary for correctness, but is an
|
|
important optimization when doing migrations. The `flush_ms` parameter controls whether
|
|
flushing should be attempted, and how much time is allowed for flushing. If the time limit expires,
|
|
the requested transition will continue without waiting for any outstanding data to flush. Callers
|
|
should use a duration which is substantially less than their HTTP client's request
|
|
timeout. It is safe to supply flush_ms irrespective of the request body: in state transitions
|
|
where flushing doesn't make sense, the server will ignore it.
|
|
|
|
It is safe to retry requests, but if one receives a 409 or 503 response, it is not
|
|
useful to retry aggressively: there is probably an existing request still ongoing.
|
|
requestBody:
|
|
required: false
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantLocationConfigRequest"
|
|
responses:
|
|
"200":
|
|
description: Tenant is now in requested state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantLocationConfigResponse"
|
|
"409":
|
|
description: |
|
|
The tenant is already being modified, perhaps by a concurrent call to this API
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
|
|
/v1/tenant/{tenant_id}/timeline/{timeline_id}/preserve_initdb_archive:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
post:
|
|
description: |
|
|
Marks the initdb archive for preservation upon deletion of the timeline or tenant.
|
|
This is meant to be part of the disaster recovery process.
|
|
responses:
|
|
"202":
|
|
description: Tenant scheduled to load successfully
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/archival_config:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
put:
|
|
description: |
|
|
Either archives or unarchives the given timeline.
|
|
An archived timeline may not have any non-archived children.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ArchivalConfigRequest"
|
|
responses:
|
|
"200":
|
|
description: Timeline (un)archived successfully
|
|
"409":
|
|
description: |
|
|
The tenant/timeline is already being modified, perhaps by a concurrent call to this API
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
"500":
|
|
description: Generic operation error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"503":
|
|
description: Temporarily unavailable, please retry.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ServiceUnavailableError"
|
|
|
|
/v1/tenant/{tenant_id}/synthetic_size:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: inputs_only
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: boolean
|
|
description: |
|
|
When true, skip calculation and only provide the model inputs (for debugging). Defaults to false.
|
|
- name: retention_period
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
description: |
|
|
Override the default retention period (in bytes) used for size calculation.
|
|
get:
|
|
description: |
|
|
Calculate tenant's size, which is a mixture of WAL (bytes) and logical_size (bytes).
|
|
responses:
|
|
"200":
|
|
description: OK,
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SyntheticSizeResponse"
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
description: SVG representation of the tenant and its timelines.
|
|
"401":
|
|
description: Unauthorized Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UnauthorizedError"
|
|
"403":
|
|
description: Forbidden Error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ForbiddenError"
|
|
"500":
|
|
description: Generic operation error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"503":
|
|
description: Temporarily unavailable, please retry.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ServiceUnavailableError"
|
|
|
|
/v1/tenant/{tenant_shard_id}/heatmap_upload:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
post:
|
|
description: |
|
|
If the location is in an attached mode, upload the current state to the remote heatmap
|
|
responses:
|
|
"200":
|
|
description: Success
|
|
|
|
/v1/tenant/{tenant_shard_id}/secondary/download:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: wait_ms
|
|
description: If set, we will wait this long for download to complete, and if it isn't complete then return 202
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
post:
|
|
description: |
|
|
If the location is in secondary mode, download latest heatmap and layers
|
|
responses:
|
|
"200":
|
|
description: Success
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SecondaryProgress"
|
|
"202":
|
|
description: Download has started but not yet finished
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SecondaryProgress"
|
|
|
|
/v1/tenant/{tenant_id}/timeline:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
post:
|
|
description: |
|
|
Create a timeline. Returns new timeline id on success.
|
|
Recreating the same timeline will succeed if the parameters match the existing timeline.
|
|
If no pg_version is specified, assume DEFAULT_PG_VERSION hardcoded in the pageserver.
|
|
|
|
To ensure durability, the caller must retry the creation until success.
|
|
Just because the timeline is visible via other endpoints does not mean it is durable.
|
|
Future versions may stop showing timelines that are not yet durable.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- new_timeline_id
|
|
properties:
|
|
new_timeline_id:
|
|
type: string
|
|
format: hex
|
|
ancestor_timeline_id:
|
|
type: string
|
|
format: hex
|
|
ancestor_start_lsn:
|
|
type: string
|
|
format: hex
|
|
pg_version:
|
|
type: integer
|
|
read_only:
|
|
type: boolean
|
|
existing_initdb_timeline_id:
|
|
type: string
|
|
format: hex
|
|
import_pgdata:
|
|
$ref: "#/components/schemas/TimelineCreateRequestImportPgdata"
|
|
responses:
|
|
"201":
|
|
description: Timeline was created, or already existed with matching parameters
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TimelineInfo"
|
|
"406":
|
|
description: Permanently unsatisfiable request, don't retry.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"409":
|
|
description: Timeline already exists, with different parameters. Creation cannot proceed.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
"429":
|
|
description: A creation request was sent for the same Timeline Id while a creation was already in progress. Back off and retry.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
get:
|
|
description: Get timelines for tenant
|
|
responses:
|
|
"200":
|
|
description: TimelineInfo
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TimelineInfo"
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/detach_ancestor:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
|
|
put:
|
|
description: |
|
|
Detach a timeline from its ancestor and reparent all ancestors timelines with lower `ancestor_lsn`.
|
|
Current implementation might not be retryable across failure cases, but will be enhanced in future.
|
|
Detaching should be expected to be expensive operation. Timeouts should be retried.
|
|
parameters:
|
|
- name: detach_behavior
|
|
in: query
|
|
required: false
|
|
schema:
|
|
description: Currently valid values are `v1`, `v2`
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: |
|
|
The timeline has been detached from it's ancestor (now or earlier), and at least the returned timelines have been reparented.
|
|
If any timelines were deleted after reparenting, they might not be on this list.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AncestorDetached"
|
|
|
|
"400":
|
|
description: |
|
|
Number of early checks meaning the timeline cannot be detached now:
|
|
- the ancestor of timeline has an ancestor: not supported, see RFC
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
|
|
"404":
|
|
description: Tenant or timeline not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/NotFoundError"
|
|
|
|
"409":
|
|
description: |
|
|
The timeline can never be detached:
|
|
- timeline has no ancestor, implying that the timeline has never had an ancestor
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
|
|
"500":
|
|
description: |
|
|
Transient error, for example, pageserver shutdown happened while
|
|
processing the request but we were unable to distinguish that. Must
|
|
be retried.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
|
|
"503":
|
|
description: |
|
|
Temporarily unavailable, please retry. Possible reasons:
|
|
- another timeline detach for the same tenant is underway, please retry later
|
|
- detected shutdown error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ServiceUnavailableError"
|
|
|
|
|
|
/v1/tenant:
|
|
get:
|
|
description: Get tenants list
|
|
responses:
|
|
"200":
|
|
description: TenantInfo
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TenantInfo"
|
|
|
|
post:
|
|
description: |
|
|
Create a tenant. Returns new tenant id on success.
|
|
|
|
If no new tenant id is specified in parameters, it would be generated. It's an error to recreate the same tenant.
|
|
|
|
Invalid fields in the tenant config will cause the request to be rejected with status 400.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantCreateRequest"
|
|
responses:
|
|
"201":
|
|
description: New tenant created successfully
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: string
|
|
"409":
|
|
description: Tenant already exists, creation skipped
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConflictError"
|
|
|
|
/v1/tenant/config:
|
|
put:
|
|
description: |
|
|
Update tenant's config by setting it to the provided value
|
|
|
|
Invalid fields in the tenant config will cause the request to be rejected with status 400.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantConfigRequest"
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TenantInfo"
|
|
patch:
|
|
description: |
|
|
Update tenant's config additively by patching the updated fields provided.
|
|
Null values unset the field and non-null values upsert it.
|
|
|
|
Invalid fields in the tenant config will cause the request to be rejected with status 400.
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantConfigRequest"
|
|
responses:
|
|
"200":
|
|
description: OK
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TenantInfo"
|
|
|
|
/v1/tenant/{tenant_id}/config:
|
|
parameters:
|
|
- name: tenant_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
get:
|
|
description: |
|
|
Returns tenant's config description: specific config overrides a tenant has
|
|
and the effective config.
|
|
responses:
|
|
"200":
|
|
description: Tenant config, specific and effective
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TenantConfigResponse"
|
|
|
|
/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/download_heatmap_layers:
|
|
parameters:
|
|
- name: tenant_shard_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: timeline_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: concurrency
|
|
description: Maximum number of concurrent downloads (capped at remote storage concurrency)
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
- name: recurse
|
|
description: When set, will recurse with the downloads into ancestor timelines
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: boolean
|
|
post:
|
|
description: |
|
|
Download all layers in the specified timeline's heatmap. The `tenant_shard_id` parameter
|
|
may be used to target all shards of a tenant when the unsharded form is used, or a specific
|
|
tenant shard with the sharded form.
|
|
responses:
|
|
"200":
|
|
description: Success
|
|
delete:
|
|
description: Stop any on-going background downloads of heatmap layers for the specified timeline.
|
|
responses:
|
|
"200":
|
|
description: Success
|
|
|
|
/v1/utilization:
|
|
get:
|
|
description: |
|
|
Returns the pageservers current utilization and fitness score for new tenants.
|
|
|
|
responses:
|
|
"200":
|
|
description: Pageserver utilization and fitness score
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/PageserverUtilization"
|
|
|
|
components:
|
|
securitySchemes:
|
|
JWT:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
schemas:
|
|
TenantInfo:
|
|
type: object
|
|
required:
|
|
- id
|
|
- attachment_status
|
|
properties:
|
|
id:
|
|
type: string
|
|
current_physical_size:
|
|
type: integer
|
|
attachment_status:
|
|
description: |
|
|
Status of this tenant's attachment to this pageserver.
|
|
|
|
- `maybe` means almost nothing, don't read anything into it
|
|
except for the fact that the pageserver _might_ be already
|
|
writing to the tenant's S3 state, so, DO NOT ATTACH the
|
|
tenant to any other pageserver, or we risk split-brain.
|
|
- `attached` means that the attach operation has completed,
|
|
successfully
|
|
- `failed` means that attach has failed. For reason check corresponding `reason` failed.
|
|
`failed` is the terminal state, retrying attach call wont resolve the issue.
|
|
For example this can be caused by s3 being unreachable. The retry may be implemented
|
|
with call to detach, though it would be better to not automate it and inspec failed state
|
|
manually before proceeding with a retry.
|
|
type: object
|
|
required:
|
|
- slug
|
|
- data
|
|
properties:
|
|
slug:
|
|
type: string
|
|
enum: [ "maybe", "attached", "failed" ]
|
|
data:
|
|
type: object
|
|
properties:
|
|
reason:
|
|
type: string
|
|
gc_blocking:
|
|
type: string
|
|
|
|
TenantCreateRequest:
|
|
allOf:
|
|
- $ref: '#/components/schemas/TenantConfig'
|
|
- $ref: '#/components/schemas/TenantLoadRequest'
|
|
- type: object
|
|
required:
|
|
- new_tenant_id
|
|
properties:
|
|
new_tenant_id:
|
|
type: string
|
|
TenantLoadRequest:
|
|
type: object
|
|
properties:
|
|
generation:
|
|
type: integer
|
|
description: Attachment generation number.
|
|
TenantConfigRequest:
|
|
allOf:
|
|
- $ref: '#/components/schemas/TenantConfig'
|
|
- type: object
|
|
required:
|
|
- tenant_id
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
TenantLocationConfigRequest:
|
|
type: object
|
|
required:
|
|
- mode
|
|
properties:
|
|
mode:
|
|
type: string
|
|
enum: ["AttachedSingle", "AttachedMulti", "AttachedStale", "Secondary", "Detached"]
|
|
description: Mode of functionality that this pageserver will run in for this tenant.
|
|
generation:
|
|
type: integer
|
|
description: Attachment generation number, mandatory when `mode` is an attached state
|
|
secondary_conf:
|
|
$ref: '#/components/schemas/SecondaryConfig'
|
|
tenant_conf:
|
|
$ref: '#/components/schemas/TenantConfig'
|
|
TenantLocationConfigResponse:
|
|
type: object
|
|
required:
|
|
- shards
|
|
properties:
|
|
shards:
|
|
description: Pageservers where this tenant's shards are attached. Not populated for secondary locations.
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TenantShardLocation"
|
|
stripe_size:
|
|
description: If multiple shards are present, this field contains the sharding stripe size, else it is null.
|
|
type: integer
|
|
nullable: true
|
|
TenantShardLocation:
|
|
type: object
|
|
required:
|
|
- node_id
|
|
- shard_id
|
|
properties:
|
|
node_id:
|
|
description: Pageserver node ID where this shard is attached
|
|
type: integer
|
|
shard_id:
|
|
description: Tenant shard ID of the shard
|
|
type: string
|
|
SecondaryConfig:
|
|
type: object
|
|
properties:
|
|
warm:
|
|
type: boolean
|
|
description: Whether to poll remote storage for layers to download. If false, secondary locations don't download anything.
|
|
ArchivalConfigRequest:
|
|
type: object
|
|
required:
|
|
- state
|
|
properties:
|
|
state:
|
|
description: The archival state of a timeline
|
|
type: string
|
|
enum: ["Archived", "Unarchived"]
|
|
TenantConfig:
|
|
type: object
|
|
properties:
|
|
gc_period:
|
|
type: string
|
|
gc_horizon:
|
|
type: integer
|
|
pitr_interval:
|
|
type: string
|
|
checkpoint_distance:
|
|
type: integer
|
|
checkpoint_timeout:
|
|
type: string
|
|
compaction_target_size:
|
|
type: integer
|
|
compaction_period:
|
|
type: string
|
|
compaction_threshold:
|
|
type: string
|
|
compaction_upper_limit:
|
|
type: string
|
|
image_creation_threshold:
|
|
type: integer
|
|
walreceiver_connect_timeout:
|
|
type: string
|
|
lagging_wal_timeout:
|
|
type: string
|
|
max_lsn_wal_lag:
|
|
type: integer
|
|
heatmap_period:
|
|
type: string
|
|
TenantConfigResponse:
|
|
type: object
|
|
properties:
|
|
tenant_specific_overrides:
|
|
$ref: "#/components/schemas/TenantConfig"
|
|
effective_config:
|
|
$ref: "#/components/schemas/TenantConfig"
|
|
TimelineCreateRequestImportPgdata:
|
|
type: object
|
|
required:
|
|
- location
|
|
- idempotency_key
|
|
properties:
|
|
idempotency_key:
|
|
type: string
|
|
location:
|
|
$ref: "#/components/schemas/TimelineCreateRequestImportPgdataLocation"
|
|
TimelineCreateRequestImportPgdataLocation:
|
|
type: object
|
|
properties:
|
|
AwsS3:
|
|
$ref: "#/components/schemas/TimelineCreateRequestImportPgdataLocationAwsS3"
|
|
TimelineCreateRequestImportPgdataLocationAwsS3:
|
|
type: object
|
|
properties:
|
|
region:
|
|
type: string
|
|
bucket:
|
|
type: string
|
|
key:
|
|
type: string
|
|
required:
|
|
- region
|
|
- bucket
|
|
- key
|
|
TimelineInfo:
|
|
type: object
|
|
required:
|
|
- timeline_id
|
|
- tenant_id
|
|
- last_record_lsn
|
|
- disk_consistent_lsn
|
|
- state
|
|
- min_readable_lsn
|
|
properties:
|
|
timeline_id:
|
|
type: string
|
|
format: hex
|
|
tenant_id:
|
|
type: string
|
|
last_record_lsn:
|
|
type: string
|
|
format: hex
|
|
disk_consistent_lsn:
|
|
type: string
|
|
format: hex
|
|
remote_consistent_lsn:
|
|
type: string
|
|
format: hex
|
|
remote_consistent_lsn_visible:
|
|
type: string
|
|
format: hex
|
|
ancestor_timeline_id:
|
|
type: string
|
|
format: hex
|
|
ancestor_lsn:
|
|
type: string
|
|
format: hex
|
|
prev_record_lsn:
|
|
type: string
|
|
format: hex
|
|
current_logical_size:
|
|
type: integer
|
|
current_physical_size:
|
|
type: integer
|
|
wal_source_connstr:
|
|
type: string
|
|
last_received_msg_lsn:
|
|
type: string
|
|
format: hex
|
|
last_received_msg_ts:
|
|
type: integer
|
|
state:
|
|
type: string
|
|
min_readable_lsn:
|
|
type: string
|
|
format: hex
|
|
applied_gc_cutoff_lsn:
|
|
type: string
|
|
format: hex
|
|
safekeepers:
|
|
$ref: "#/components/schemas/TimelineSafekeepersInfo"
|
|
|
|
TimelineSafekeepersInfo:
|
|
type: object
|
|
required:
|
|
- tenant_id
|
|
- timeline_id
|
|
- generation
|
|
- safekeepers
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
format: hex
|
|
timeline_id:
|
|
type: string
|
|
format: hex
|
|
generation:
|
|
type: integer
|
|
safekeepers:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TimelineSafekeeperInfo"
|
|
|
|
TimelineSafekeeperInfo:
|
|
type: object
|
|
required:
|
|
- id
|
|
- hostname
|
|
properties:
|
|
id:
|
|
type: integer
|
|
hostname:
|
|
type: string
|
|
|
|
SyntheticSizeResponse:
|
|
type: object
|
|
required:
|
|
- id
|
|
- size
|
|
- segment_sizes
|
|
- inputs
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: hex
|
|
size:
|
|
type: integer
|
|
nullable: true
|
|
description: |
|
|
Size metric in bytes or null if inputs_only=true was given.
|
|
segment_sizes:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SegmentSize"
|
|
inputs:
|
|
type: object
|
|
properties:
|
|
segments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/SegmentData"
|
|
timeline_inputs:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TimelineInput"
|
|
|
|
SegmentSize:
|
|
type: object
|
|
required:
|
|
- method
|
|
- accum_size
|
|
properties:
|
|
method:
|
|
type: string
|
|
accum_size:
|
|
type: integer
|
|
|
|
SegmentData:
|
|
type: object
|
|
required:
|
|
- segment
|
|
properties:
|
|
segment:
|
|
type: object
|
|
required:
|
|
- lsn
|
|
properties:
|
|
parent:
|
|
type: integer
|
|
lsn:
|
|
type: integer
|
|
size:
|
|
type: integer
|
|
needed:
|
|
type: boolean
|
|
timeline_id:
|
|
type: string
|
|
format: hex
|
|
kind:
|
|
type: string
|
|
|
|
TimelineInput:
|
|
type: object
|
|
required:
|
|
- timeline_id
|
|
properties:
|
|
ancestor_id:
|
|
type: string
|
|
ancestor_lsn:
|
|
type: string
|
|
timeline_id:
|
|
type: string
|
|
format: hex
|
|
|
|
LsnByTimestampResponse:
|
|
type: object
|
|
required:
|
|
- lsn
|
|
- kind
|
|
properties:
|
|
lsn:
|
|
type: string
|
|
format: hex
|
|
kind:
|
|
type: string
|
|
enum: [past, present, future, nodata]
|
|
valid_until:
|
|
type: string
|
|
format: date-time
|
|
description: The expiration time of the granted lease.
|
|
|
|
LsnLease:
|
|
type: object
|
|
required:
|
|
- valid_until
|
|
properties:
|
|
valid_until:
|
|
type: string
|
|
format: date-time
|
|
|
|
PageserverUtilization:
|
|
type: object
|
|
required:
|
|
- disk_usage_bytes
|
|
- free_space_bytes
|
|
- utilization_score
|
|
properties:
|
|
disk_usage_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: The amount of disk space currently used.
|
|
free_space_bytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
description: The amount of usable disk space left.
|
|
utilization_score:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
maximum: 9223372036854775807
|
|
default: 9223372036854775807
|
|
description: |
|
|
Lower is better score for how good this pageserver would be for the next tenant.
|
|
The default or maximum value can be returned in situations when a proper score cannot (yet) be calculated.
|
|
|
|
SecondaryProgress:
|
|
type: object
|
|
required:
|
|
- heatmap_mtime
|
|
- layers_downloaded
|
|
- layers_total
|
|
- bytes_downloaded
|
|
- bytes_total
|
|
properties:
|
|
heatmap_mtime:
|
|
type: string
|
|
format: date-time
|
|
description: Modification time of the most recently downloaded layer heatmap (RFC 3339 format)
|
|
layers_downloaded:
|
|
type: integer
|
|
format: int64
|
|
description: How many layers from the latest layer heatmap are present on disk
|
|
bytes_downloaded:
|
|
type: integer
|
|
format: int64
|
|
description: How many bytes of layer content from the latest layer heatmap are present on disk
|
|
layers_total:
|
|
type: integer
|
|
format: int64
|
|
description: How many layers were in the latest layer heatmap
|
|
bytes_total:
|
|
type: integer
|
|
format: int64
|
|
description: How many bytes of layer content were in the latest layer heatmap
|
|
|
|
AncestorDetached:
|
|
type: object
|
|
required:
|
|
- reparented_timelines
|
|
properties:
|
|
reparented_timelines:
|
|
type: array
|
|
description: Set of reparented timeline ids
|
|
items:
|
|
type: string
|
|
format: hex
|
|
description: TimelineId
|
|
|
|
|
|
Error:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
UnauthorizedError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
ForbiddenError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
ServiceUnavailableError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
NotFoundError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
ConflictError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
PreconditionFailedError:
|
|
type: object
|
|
required:
|
|
- msg
|
|
properties:
|
|
msg:
|
|
type: string
|
|
|
|
security:
|
|
- JWT: []
|