대기열 · Vault · GraphQL · 접속 제한
pgmq와 같은 대기열, 데이터베이스 안의 암호화된 비밀(Vault), /graphql/v1, 직접 연결의 주소 제한과 TLS.
대기열, Vault, GraphQL, 접속 제한
모두 전용 데이터베이스(p_<ref>)에 있는 프로젝트에서 써요. 새 프로젝트는 처음부터 전용 데이터베이스예요.
대기열 (pgmq)
pgmq와 같은 SQL 함수예요. create_queue가 처음이면 pgmq 스키마를 설치해요.
select pgmq.create('jobs');
select * from pgmq.send('jobs', '{"to": "[email protected]"}');
select * from pgmq.read('jobs', 30, 10);
select pgmq.archive('jobs', 1);
select pgmq.delete('jobs', 2);
select * from pgmq.pop('jobs');
select * from pgmq.metrics('jobs');도구: list_queues, create_queue, send_queue_message, peek_queue(가져가지 않고 보기), purge_queue,
delete_queue, set_queues_api. 대기열 표 pgmq.q_<이름>은 서비스 역할의 것이고 접근 규칙이 켜져 있어요.
set_queues_api { exposed: true }면 데이터 API에서 부를 수 있어요.
await supabase.schema('pgmq_public').rpc('send', { queue_name: 'jobs', message: { hello: 'world' } })
await supabase.schema('pgmq_public').rpc('read', { queue_name: 'jobs', sleep_seconds: 30, n: 5 })공개 키·로그인 사용자가 쓰려면 SQL로 권한과 규칙을 줘요.
grant insert, select, update on pgmq.q_jobs to authenticated;
create policy "own jobs" on pgmq.q_jobs for all to authenticated using (true) with check (true);Vault
비밀을 암호화해 프로젝트 데이터베이스의 vault.secrets에 저장해요. 키는 플랫폼이 갖고 있고 데이터베이스에
저장되지 않아서 덤프·백업·브랜치에는 암호문만 남아요. 비밀 키(서비스 역할)로 읽을 때만 풀려요.
select vault.create_secret('sk_live_...', 'stripe_key', 'Stripe');
select decrypted_secret from vault.decrypted_secrets where name = 'stripe_key';
select vault.update_secret('<id>', 'sk_live_new');도구: list_vault_secrets(이름만), create_vault_secret, update_vault_secret, delete_vault_secret.
공개 키와 로그인 사용자는 vault 스키마를 볼 수 없고, 직접 연결(<ref>_db)에서는 decrypted_secret이 null이에요.
전용 데이터베이스로 옮기기
Vault와 큰 데이터베이스는 전용 데이터베이스에서만 쓸 수 있어요(Pro 요금제부터). get_database_move가 지금 어디에 있는지와
옮기기 상태를 보여 주고, move_to_dedicated_database가 콘솔의 "지금 옮기기"처럼 옮기기를 요청해요(소유자·관리자).
차례가 오면 옮기고, 옮기는 동안 쓰기는 멈추고 읽기는 돼요. REST: GET·POST /projects/<ref>/database/move,
CLI: oneend db move, oneend db move now.
전용 디스크
데이터베이스가 커진 유료 프로젝트는 함께 쓰는 디스크에서 이 프로젝트 전용 디스크와 Postgres로 옮겨요(Supabase의
프로젝트별 서버와 볼륨처럼). 데이터베이스가 20GB를 넘으면 자동으로 옮기고(지출 상한이 꺼진 조직 또는 Enterprise), Enterprise는
크기와 관계없이 요청할 수 있어요. 디스크는 max(1.2 × 데이터베이스, 20GB)로 시작해 75% 넘게 차면 1.5배로 늘어나고(4시간에 한 번까지),
만든 크기만큼 GB당 월 ₩1,200(75¢)로 청구돼요. 옮기는 동안 쓰기가 실패하고 읽기는 돼요(expected_downtime_seconds). 연결 주소와
비밀번호는 그대로예요. 옮긴 뒤에는 특정 시각으로 복원할 수 없고, 매일 받는 백업으로 복원해요.
get_dedicated_disk가 디스크 크기, 쓴 공간, 한 달 비용, 30일 기록, 줄이기 제안을 보여 주고, request_dedicated_disk가 옮기기를,
shrink_dedicated_disk가 줄이기를 요청해요(소유자·관리자). 디스크는 저절로 줄지 않아요: 7일 동안 25% 아래로 쓰면 줄이기를 제안하고,
확인하면 더 작은 디스크를 만들어 옮긴 뒤 원래 디스크를 지워요. 프로젝트를 지우면 30일 뒤 디스크도 지워져 비용이 0이 돼요.
REST: GET·POST /projects/<ref>/database/dedicated-disk, POST /projects/<ref>/database/dedicated-disk/shrink,
CLI: oneend db disk, oneend db disk request, oneend db disk shrink.
전용 서버
Pro부터 프로젝트 하나만 쓰는 서버를 빌릴 수 있어요(앱과 데이터베이스가 함께 쓰고, 데이터베이스가 메모리의 25%). 크기와 위치별 월 금액은
list_server_sizes가 보여 주고, 여기에는 적지 않아요. get_server가 지금 서버·대기 서버·작업을, request_server(tier, region)가 빌리기를,
resize_server(tier, when=now|tonight)가 크기 바꾸기를(대기 서버가 없으면 3~5분 응답 없음), set_standby(standby, auto_failover)가 대기
서버와 자동 전환(60초 응답 없음)을, move_server(region)가 위치 옮기기를(무료, 한 달에 한 번, 옛 서버 7일 보관), release_server(confirm=ref)가
반납을, set_restore_days(7|28)가 되돌리기 기간을 정해요. 결제가 실패하면 7일 동안 읽기 전용이 되고, 그 뒤 마지막 백업을 받고 서버를 지워요.
REST: GET·POST·PATCH·DELETE /projects/<ref>/server, PUT /projects/<ref>/server/standby, POST /projects/<ref>/server/move,
PUT /projects/<ref>/server/restore-days. CLI: oneend server, oneend server request|resize|standby|move|release|restore-days.
GraphQL
enable_extension { ref, name: "pg_graphql" }로 켜면 /graphql/v1이 열려요. 키와 접근 규칙은 /rest/v1과 같아요.
POST https://<ref>.<zone>/graphql/v1
apikey: <publishable key>
{"query": "{ todosCollection { edges { node { id title } } } }"}직접 연결의 접속 제한과 TLS
get_network_restrictions, update_network_restrictions { ref, allowed_cidrs: ["203.0.113.0/24"], enforce_ssl: true }.
기본값은 모든 주소 허용, TLS 필수예요. 요청을 보낸 주소가 목록에 없으면 confirm: true 없이는 저장되지 않아요.
콘솔·API·run_sql은 연결 풀러를 거치지 않아서 제한을 잘못 걸어도 여기서 되돌릴 수 있어요.
읽기 전용 복제본
아직 없어요. 운영 대기 서버는 장애 대비용이라 고객 연결을 받지 않아요.
HTTP로는 GET /queues, POST /queues, POST /queues/<이름>/messages, GET /queues/<이름>/messages,
POST /queues/<이름>/purge, DELETE /queues/<이름>, PUT /queues/api, GET /vault, POST /vault,
PATCH /vault/<이름>, DELETE /vault/<이름>, GET /network-restrictions, PUT /network-restrictions이에요.