> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Volumes

> Criar um volume, os tipos oferecidos, anexá-lo a uma instância, aumentá-lo e excluí-lo.

<a id="creating-a-volume" />

## Criando um volume

A criação é assíncrona. `POST /v1/volumes` responde **`202`** com o volume em `creating`; consulta `GET /v1/volumes/{volume_id}` até que `status` se torne `available` ou `error`. `error` significa uma falha de erro ativa — leia `faults`. Veja [Falhas de recursos](/pt/resource-faults).

<Tabs>
  <Tab title="Console">
    Vá para **Storage → Volumes** e escolha **Create Volume**. Dê um **Name**, deixe **Source** em **Blank volume**, defina **Size (GB)** e escolha um **Tier** — **SSD** ou **NVMe**. O cartão **Tags** usa os mesmos pares de chave/valor que a API.

    Ambas as camadas incluem 3.000 IOPS e 125 MiB/s, independentemente do tamanho. Você pode provisionar IOPS e taxa de transferência adicionais nos campos de desempenho.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST https://storage.sa-saopaulo-1.basaltic.sh/v1/volumes
    {
      "name": "app-data-01",
      "volume_type": "ssd",
      "size_gb": 100,
      "tags": { "env": "production" }
    }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic storage volume create \
      --name app-data-01 --volume-type ssd --size-gb 100 \
      --tags env=production
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    cfg, err := basaltic.NewConfig(ctx,
        basaltic.WithClientCredentials(os.Getenv("BASALTIC_ACCESS_KEY_ID"), os.Getenv("BASALTIC_SECRET_ACCESS_KEY")),
        basaltic.WithRegion("sa-saopaulo-1"),
    )
    if err != nil {
        log.Fatal(err)
    }

    vol, err := storage.New(cfg).CreateVolume(ctx, &storage.VolumeCreateRequest{
        Name:       "app-data-01",
        VolumeType: "ssd",
        SizeGB:     100,
        Tags:       storage.Tags{"env": "production"},
    })
    ```

    A chamada retorna com o volume em `creating`; poll `GetVolume` até que ele chegue a `available`.
  </Tab>
</Tabs>

<ResponseField name="name" type="unique within your account">
  Correspondências `^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$`. Ele aparece no CRN, então ele tem que ser seguro para URLs. Um nome duplicado é `409 VOLUME_NAME_EXISTS`. O nome é fixo após a criação porque as políticas do IAM abordam o volume por seu CRN. Atualizações contendo `name` retornam um erro de validação, incluindo valores inalterados, vazios ou `null`. Os volumes existentes mantêm os seus nomes actuais.
</ResponseField>

<ResponseField name="size_gb" type="1–16384" required>
  O limite corresponde ao que um dispositivo de bloco único é limitado em outros lugares na indústria. É um limite de sanidade por volume, não sua cota — o uso agregado é limitado separadamente.
</ResponseField>

<ResponseField name="volume_type" type="ssd | nvme" required>
  Veja abaixo. `GET /v1/volume-types` lista exatamente o que você pode criar.
</ResponseField>

<Tip>
  Envie um cabeçalho `Idempotency-Key`. Tentar novamente com a mesma chave retorna o resultado original em vez de criar um segundo volume; reutilizar a chave com um corpo diferente é rejeitado com `422`.
</Tip>

<a id="volume-types" />

## Tipos de volume

`GET /v1/volume-types` lista as camadas de armazenamento disponíveis. Os novos volumes em ambas as camadas incluem **3.000 IOPS e 125 MiB/s**, independentemente da capacidade.

<Columns cols={2}>
  <Card title="ssd" icon="gauge">
    Armazenamento em bloco SSD com **3.000 IOPS / 125 MiB/s** incluído.
  </Card>

  <Card title="NVME" icon="zap">
    Armazenamento em bloco NVMe com **3.000 IOPS / 125 MiB/s** incluído.
  </Card>
</Columns>

Os limites aplicam-se a leituras e gravações combinadas, por volume. Qualquer limite que a carga de trabalho atinja primeiro determina sua taxa máxima. Todos os volumes têm limites sustentados sem créditos de explosão. Aumentar a capacidade não aumenta as IOPS ou a taxa de transferência.

Os volumes existentes e novos incluem exatamente **3.000 IOPS/125 MiB/s**, sem exceções baseadas em capacidade ou créditos de burst. O desempenho adicional é ativado somente quando você o provisiona explicitamente. A resposta `included_io_limits` do volume e seus detalhes de console mostram essa linha de base fixa. `bytes_per_sec` é expresso em bytes por segundo; 125 MiB/s é 131.072.000 bytes por segundo.

<Info>
  Esses limites são limites de desempenho, não uma garantia de latência. Os resultados reais dependem do tamanho da operação, da concorrência, da carga de trabalho do convidado e da capacidade de armazenamento disponível. A 4 KiB por operação, 3.000 IOPS são aproximadamente 11,72 MiB/s; alcançar 125 MiB/s requer operações maiores.
</Info>

O tipo é fixo na criação, e não há chamada que o mude. Mover para uma camada diferente significa criar um volume do tipo desejado e copiar os dados de dentro do convidado.

<a id="provisioning-more-performance" />

## Provisionando mais desempenho

Aumente as IOPS, a taxa de transferência ou ambas sem aumentar a capacidade do disco ou reiniciar a instância. Os totais selecionáveis para um volume padrão são:

| Tipo | IOPS / MiB/s incluídos | Máximo de IOPS / MiB/s |
| - | - | - |
| SSD | 3,000 / 125 | 8,000 / 250 |
| NVMe Memórias | 3,000 / 125 | 12,000 / 500 |

O desempenho adicional custa **R$ 0,02 por IOPS-mês** e **R$ 0,20 por MiB/s-mês**, acima dos 3.000 IOPS / 125 MiB/s incluídos. As mesmas taxas se aplicam a ambos os níveis. A 3.000 IOPS e 500 MiB/s, um volume NVMe padrão adiciona R$75 por um mês inteiro; a 12.000 IOPS e 500 MiB/s adiciona R$255. A capacidade de armazenamento é cobrada separadamente. Leia as taxas atuais do [catálogo de preços públicos](/pt/billing#the-public-price-catalogue), filtrado com `resource_type=volume-performance`.

As cobranças são proporcionais a partir do momento em que uma configuração é aplicada, usando o tempo decorrido no mês de faturamento UTC real. Você paga pela alocação provisionada mesmo quando um volume está desconectado ou sua instância está parada. As operações reais e os bytes transferidos não determinam essa cobrança. Voltar para a cota incluída remove a cobrança extra assim que os limites inferiores forem aplicados; excluir o volume também encerra a alocação.

<Tabs>
  <Tab title="Console">
    Abra o volume em **Storage → Volumes** e escolha **Change performance**. Defina **Provisioned IOPS** e **Provisioned throughput (MiB/s)**, revise o preço mensal adicional e aplique a alteração. **Use included performance** restaura os valores incluídos no formulário; aplique-os para remover o complemento.

    Você também pode escolher essas configurações ao criar um volume. O **Summary** mostra **Additional performance** separadamente da capacidade de armazenamento e adiciona-o uma vez ao total. Por exemplo, 3.500 IOPS / 250 MiB/s adiciona R\$35/mês. [Criação de instância](/pt/compute/instances#performance-and-existing-disks) oferece os mesmos controles para cada novo disco de inicialização e dados.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST https://storage.sa-saopaulo-1.basaltic.sh/v1/volumes/{volume_id}/performance
    {
      "iops": 6000,
      "throughput_mib_s": 250
    }
    ```

    Envie um cabeçalho `Idempotency-Key` para retenções seguras. Para selecionar performance durante a criação, coloque os mesmos campos no objeto `performance` da solicitação.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic storage volume update-performance <volume-id> \
      --iops 6000 --throughput-mib-s 250 \
      --idempotency-key report-volume-performance-1
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    iops, throughput := 6000, 250.0
    vol, err := storage.New(cfg).UpdateVolumePerformance(ctx, volumeID,
        &storage.VolumePerformanceRequest{
            IOPS:           &iops,
            ThroughputMiBS: &throughput,
        }, basaltic.WithIdempotencyKey("report-volume-performance-1"))
    ```
  </Tab>
</Tabs>

A API retorna `202`. Sonda o volume até que `performance.state` seja `applied`. `performance.requested` é o alvo, enquanto `performance.applied` é a configuração reconhecida. Esses objetos expressam o throughput como `bytes_per_sec`. A tarifa antiga aplicada continua a ser cobrada enquanto uma alteração estiver pendente. Se uma alteração for atrasada, a resposta inclui o ID da operação e o último erro.

Pelo menos uma dimensão é necessária para uma atualização; as dimensões omitidas mantêm seus valores atuais. Use IOPS inteiros e MiB/s. Uma fração exata da taxa de transferência de legado também pode ser selecionada para remover extras. Os valores devem ficar entre a cota incluída do volume e o limite máximo da camada; qualquer cota incluída superior permanece disponível sem custo adicional. Redimensionamento, reinicialização, reanexação e migração preservam sua seleção.

Um aumento também requer cota de conta, capacidade regional e armazenamento saudável. Um aumento rejeitado não cria uma nova alocação faturável. Se outra alteração estiver pendente, tente novamente o mesmo destino ou aguarde que ele seja concluído antes de escolher um destino diferente. Esses permanecem como limites combinados de leitura/gravação no armazenamento compartilhado, não uma reserva dedicada ou uma garantia de latência.

<a id="attaching-to-an-instance" />

## Anexando a uma instância

O anexo é uma operação de computação — a vinculação de dispositivo, o hot-plug de convidado e a ordem de inicialização estão todos no lado da instância:

<Tabs>
  <Tab title="Console">
    Abra o volume em **Storage → Volumes** e escolha **Attach to
    instance**. Escolha a **Instance**; **Device name**, **Mount path** e **Filesystem** são opcionais. Deixar **Device name** em branco atribui o próximo nome disponível e definir um **Mount path** monta o volume lá dentro do convidado — formatando-o primeiro somente se estiver em branco.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/instances/{instance_id}/volumes
    { "volume": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance attach-volume <instance-id> --volume <volume-id>
    ```

    `--device`, `--mount-path` e `--fstype` são opcionais e se comportam como os campos do console.
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    att, err := compute.New(cfg).AttachInstanceVolume(ctx, instanceID,
        &compute.AttachInstanceVolumeRequest{
            Volume: volumeID,
        })
    ```

    O anexo reside no cliente de computação, não no armazenamento — a vinculação de dispositivo e a ordem de inicialização pertencem à instância.
  </Tab>
</Tabs>

O volume passa de `available` para `in_use`, e a separação o coloca de volta para `available`. Veja [compute](/pt/compute) para os slots de dispositivos, opções de montagem e a chamada detach.

<Warning>
  **Um volume é anexado a uma instância de cada vez.** Não há multi-anexação: a vinculação é exclusiva por volume, portanto, uma segunda anexação é recusada em vez de entregar a dois convidados o mesmo dispositivo de bloco.
</Warning>

<a id="what-happens-when-the-instance-is-deleted" />

### O que acontece quando a instância é excluída

Cada anexo carrega um sinalizador `delete_on_termination`, e o padrão difere de acordo com como o volume chegou lá:

| Volume de vendas | `delete_on_termination` | Resultado quando a instância é excluída |
| - | - | - |
| Volume de inicialização criado com a instância | `true` | Destruiu com a instância. |
| Volume de dados que você anexou | `false` | Sobrevive, retorna para `available`. |

`PATCH /v1/instances/{instance_id}/volumes/{volume_id}` muda o sinalizador em um anexo existente. Defina-o deliberadamente em qualquer coisa que contenha dados que você se importa — o volume de inicialização padrão é aquele que exclui.

No console, o sinalizador é um **Delete on termination** na lista de volumes anexados da **instância**, não na própria página do volume. Pertence ao apego, então é aí que ele vive.

O disco de inicialização em si não pode ser desconectado: desconectá-lo levaria o sistema de arquivos root do convidado com ele, então a chamada é recusada.
[crescer enquanto estiver ligado](#growing-a-volume).

<a id="growing-a-volume" />

## Crescendo um volume

<Tabs>
  <Tab title="Console">
    Abra o volume e escolha **Extend**, ou use a ação de linha **Extend** em **Storage → Volumes**. A caixa de diálogo **Extend Volume** mostra **Current Size** e assume um **New Size (GB)**.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/volumes/{volume_id}/extend
    { "new_size_gb": 200 }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic storage volume extend <volume-id> --new-size-gb 200
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    vol, err := storage.New(cfg).ExtendVolume(ctx, volumeID, &storage.VolumeExtendRequest{
        NewSizeGB: 200,
    })
    ```
  </Tab>
</Tabs>

A chamada responde **`202`** com o volume em `extending` e retorna para `available` para um volume separado ou `in_use` para um volume anexado, no novo tamanho. Os volumes de inicialização e de dados podem crescer com a instância em execução ou parada; nenhum desligamento é necessário. `new_size_gb` deve ser estritamente maior que o tamanho atual; qualquer outra coisa é `400 VOLUME_SIZE_INVALID`.

<Warning>
  **Um volume não pode ser encolhido.** Não há chamada que reduza `size_gb`, e a cota que você comprometeu no tamanho maior permanece comprometida. Cresça nos passos que você realmente precisa.
</Warning>

O crescimento do volume não aumenta sua partição ou sistema de arquivos. Aguarde até que o volume saia de `extending`, então verifique o tamanho do dispositivo dentro do guest:

```bash theme={null}
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS
```

O dispositivo de bloco da instância é atualizado automaticamente. Se o convidado ainda mostrar o tamanho antigo, use o método de nova verificação suportado pelo driver de dispositivo ou reinicie a instância. Para um driver que expõe um arquivo de rescan (nem todos os dispositivos de bloco virtio fazem isso), o comando é:

```bash theme={null}
# Only if this file exists and vda is the volume you extended:
echo 1 | sudo tee /sys/class/block/vda/device/rescan
```

Para **um sistema de arquivos ext4 diretamente na partição 1 de `/dev/vda`**, com espaço livre imediatamente após essa partição, o seguinte aumenta a partição e o sistema de arquivos. Confirme o dispositivo e o layout com `lsblk` primeiro e faça um backup. Esses comandos são executados dentro da sua instância; eles não são executados pelo serviço.

```bash theme={null}
sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1
```

Para um volume ext4 não particionado, execute `resize2fs` no dispositivo do volume e pule `growpart`. XFS, LVM, discos encriptados e outros layouts de partição precisam dos seus próprios passos de crescimento; não use o exemplo ext4 para eles.

<a id="deleting-a-volume" />

## Excluindo um volume

`DELETE /v1/volumes/{volume_id}` responde **`202`**, inverte a linha para `deleting` e destrói o volume de forma assíncrona. Sondagem até que o volume desapareça.

Duas recusas de saber sobre:

<AccordionGroup>
  <Accordion title="409 - Não encontrado" icon="link">
    O volume está anexado. Desconecte-o da instância primeiro. Delete também é recusado durante os estados transitórios — `creating`, `extending`, `deleting` — então uma segunda operação não pode competir com a primeira.
  </Accordion>

  <Accordion title="409 - Não encontrado" icon="camera">
    Um volume que ainda tenha instantâneos não será excluído, porque esses instantâneos são filhos dos dados do volume e não é possível remover o pai abaixo deles. Apague os instantâneos primeiro, depois o volume.

    Esta é uma recusa limpa em vez de um desmantelamento parcial, então nada é perdido ao tentar.
  </Accordion>
</AccordionGroup>

Excluir um volume também remove todas as suas [snapshot policies](/pt/storage/snapshots#snapshot-policies) — as agendas não têm mais nada para fazer snapshots. Sua cota é liberada quando o teardown termina, não quando a chamada é aceita, para que a capacidade e o uso relatado permaneçam alinhados enquanto uma exclusão está em andamento.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.