mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-18 21:26:56 +00:00
Decoding EC shards back to a normal volume in place reconstructs <vid>.dat
in the shards' own directory, so the vid is momentarily registered as both
an EC and a normal volume in one location — the load/scan path then sees it
as both, risking mount ambiguity and needle loss. VolumeEcShardsToVolume
still supports that in-place path; this adds the primitives to decode onto
a *clean* peer instead:
- ReceiveFile gains a staged-new-volume mode: when the volume does not
exist here and ReceiveFileInfo.disk_type is set, pick a free-slot disk
of that medium and write <base><ext>.copying (not a valid volume name,
so the scanner never half-loads a partial push).
- VolumeEcShardsToVolume gains from_staged: adopt the pushed .dat/.idx/
.vif — rename .copying into place under a .note in-progress marker,
then mount — so <vid> lands on the peer only as a normal volume.
The caller decodes the shards off-box and streams the finished volume to a
peer holding no shard of the vid on the target medium. Go and Rust volume
servers get identical handlers. Proto: ReceiveFileInfo.disk_type (12; 8-11
reserved for versioned-EC), VolumeEcShardsToVolumeRequest.from_staged (3) +
disk_type (4).
Claude-Session: https://claude.ai/code/session_01Ks16jnt4S7gdDk8cheQ3xu
826 lines
24 KiB
Protocol Buffer
826 lines
24 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
package volume_server_pb;
|
|
option go_package = "github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb";
|
|
|
|
import "remote.proto";
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
// Persistent state for volume servers.
|
|
message VolumeServerState {
|
|
// whether the server is in maintenance (i.e. read-only) mode.
|
|
bool maintenance = 1;
|
|
// incremental version counter
|
|
uint32 version = 2;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
service VolumeServer {
|
|
//Experts only: takes multiple fid parameters. This function does not propagate deletes to replicas.
|
|
rpc BatchDelete (BatchDeleteRequest) returns (BatchDeleteResponse) {
|
|
}
|
|
|
|
rpc VacuumVolumeCheck (VacuumVolumeCheckRequest) returns (VacuumVolumeCheckResponse) {
|
|
}
|
|
rpc VacuumVolumeCompact (VacuumVolumeCompactRequest) returns (stream VacuumVolumeCompactResponse) {
|
|
}
|
|
rpc VacuumVolumeCommit (VacuumVolumeCommitRequest) returns (VacuumVolumeCommitResponse) {
|
|
}
|
|
rpc VacuumVolumeCleanup (VacuumVolumeCleanupRequest) returns (VacuumVolumeCleanupResponse) {
|
|
}
|
|
|
|
rpc DeleteCollection (DeleteCollectionRequest) returns (DeleteCollectionResponse) {
|
|
}
|
|
rpc AllocateVolume (AllocateVolumeRequest) returns (AllocateVolumeResponse) {
|
|
}
|
|
|
|
rpc VolumeSyncStatus (VolumeSyncStatusRequest) returns (VolumeSyncStatusResponse) {
|
|
}
|
|
rpc VolumeIncrementalCopy (VolumeIncrementalCopyRequest) returns (stream VolumeIncrementalCopyResponse) {
|
|
}
|
|
|
|
rpc VolumeMount (VolumeMountRequest) returns (VolumeMountResponse) {
|
|
}
|
|
rpc VolumeUnmount (VolumeUnmountRequest) returns (VolumeUnmountResponse) {
|
|
}
|
|
rpc VolumeConsolidateIndex (VolumeConsolidateIndexRequest) returns (VolumeConsolidateIndexResponse) {
|
|
}
|
|
rpc VolumeDelete (VolumeDeleteRequest) returns (VolumeDeleteResponse) {
|
|
}
|
|
rpc VolumeMarkReadonly (VolumeMarkReadonlyRequest) returns (VolumeMarkReadonlyResponse) {
|
|
}
|
|
rpc VolumeMarkWritable (VolumeMarkWritableRequest) returns (VolumeMarkWritableResponse) {
|
|
}
|
|
rpc VolumeConfigure (VolumeConfigureRequest) returns (VolumeConfigureResponse) {
|
|
}
|
|
rpc VolumeStatus (VolumeStatusRequest) returns (VolumeStatusResponse) {
|
|
}
|
|
|
|
rpc GetState (GetStateRequest) returns (GetStateResponse) {
|
|
}
|
|
rpc SetState (SetStateRequest) returns (SetStateResponse) {
|
|
}
|
|
|
|
// copy the .idx .dat files, and mount this volume
|
|
rpc VolumeCopy (VolumeCopyRequest) returns (stream VolumeCopyResponse) {
|
|
}
|
|
rpc ReadVolumeFileStatus (ReadVolumeFileStatusRequest) returns (ReadVolumeFileStatusResponse) {
|
|
}
|
|
rpc CopyFile (CopyFileRequest) returns (stream CopyFileResponse) {
|
|
}
|
|
rpc ReceiveFile (stream ReceiveFileRequest) returns (ReceiveFileResponse) {
|
|
}
|
|
|
|
rpc ReadNeedleBlob (ReadNeedleBlobRequest) returns (ReadNeedleBlobResponse) {
|
|
}
|
|
rpc ReadNeedleMeta (ReadNeedleMetaRequest) returns (ReadNeedleMetaResponse) {
|
|
}
|
|
rpc WriteNeedleBlob (WriteNeedleBlobRequest) returns (WriteNeedleBlobResponse) {
|
|
}
|
|
rpc ReadAllNeedles (ReadAllNeedlesRequest) returns (stream ReadAllNeedlesResponse) {
|
|
}
|
|
|
|
rpc VolumeTailSender (VolumeTailSenderRequest) returns (stream VolumeTailSenderResponse) {
|
|
}
|
|
rpc VolumeTailReceiver (VolumeTailReceiverRequest) returns (VolumeTailReceiverResponse) {
|
|
}
|
|
|
|
// erasure coding
|
|
rpc VolumeEcShardsGenerate (VolumeEcShardsGenerateRequest) returns (VolumeEcShardsGenerateResponse) {
|
|
}
|
|
rpc VolumeEcShardsRebuild (VolumeEcShardsRebuildRequest) returns (VolumeEcShardsRebuildResponse) {
|
|
}
|
|
rpc VolumeEcShardsCopy (VolumeEcShardsCopyRequest) returns (VolumeEcShardsCopyResponse) {
|
|
}
|
|
rpc VolumeEcShardsDelete (VolumeEcShardsDeleteRequest) returns (VolumeEcShardsDeleteResponse) {
|
|
}
|
|
rpc VolumeEcShardsMount (VolumeEcShardsMountRequest) returns (VolumeEcShardsMountResponse) {
|
|
}
|
|
rpc VolumeEcShardsUnmount (VolumeEcShardsUnmountRequest) returns (VolumeEcShardsUnmountResponse) {
|
|
}
|
|
rpc VolumeEcShardRead (VolumeEcShardReadRequest) returns (stream VolumeEcShardReadResponse) {
|
|
}
|
|
rpc VolumeEcBlobDelete (VolumeEcBlobDeleteRequest) returns (VolumeEcBlobDeleteResponse) {
|
|
}
|
|
rpc VolumeEcShardsToVolume (VolumeEcShardsToVolumeRequest) returns (VolumeEcShardsToVolumeResponse) {
|
|
}
|
|
rpc VolumeEcShardsInfo (VolumeEcShardsInfoRequest) returns (VolumeEcShardsInfoResponse) {
|
|
}
|
|
|
|
// tiered storage
|
|
rpc VolumeTierMoveDatToRemote (VolumeTierMoveDatToRemoteRequest) returns (stream VolumeTierMoveDatToRemoteResponse) {
|
|
}
|
|
rpc VolumeTierMoveDatFromRemote (VolumeTierMoveDatFromRemoteRequest) returns (stream VolumeTierMoveDatFromRemoteResponse) {
|
|
}
|
|
|
|
rpc VolumeServerStatus (VolumeServerStatusRequest) returns (VolumeServerStatusResponse) {
|
|
}
|
|
rpc VolumeServerLeave (VolumeServerLeaveRequest) returns (VolumeServerLeaveResponse) {
|
|
}
|
|
|
|
// remote storage
|
|
rpc FetchAndWriteNeedle (FetchAndWriteNeedleRequest) returns (FetchAndWriteNeedleResponse) {
|
|
}
|
|
|
|
// scrubbing
|
|
rpc ScrubVolume (ScrubVolumeRequest) returns (ScrubVolumeResponse) {
|
|
}
|
|
rpc ScrubEcVolume (ScrubEcVolumeRequest) returns (ScrubEcVolumeResponse) {
|
|
}
|
|
|
|
// <experimental> query
|
|
rpc Query (QueryRequest) returns (stream QueriedStripe) {
|
|
}
|
|
|
|
rpc VolumeNeedleStatus (VolumeNeedleStatusRequest) returns (VolumeNeedleStatusResponse) {
|
|
}
|
|
|
|
rpc Ping (PingRequest) returns (PingResponse) {
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
message BatchDeleteRequest {
|
|
repeated string file_ids = 1;
|
|
bool skip_cookie_check = 2;
|
|
}
|
|
|
|
message BatchDeleteResponse {
|
|
repeated DeleteResult results = 1;
|
|
}
|
|
message DeleteResult {
|
|
string file_id = 1;
|
|
int32 status = 2;
|
|
string error = 3;
|
|
uint32 size = 4;
|
|
uint32 version = 5;
|
|
}
|
|
|
|
message Empty {
|
|
}
|
|
|
|
message VacuumVolumeCheckRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VacuumVolumeCheckResponse {
|
|
double garbage_ratio = 1;
|
|
}
|
|
|
|
message VacuumVolumeCompactRequest {
|
|
uint32 volume_id = 1;
|
|
int64 preallocate = 2;
|
|
}
|
|
message VacuumVolumeCompactResponse {
|
|
int64 processed_bytes = 1;
|
|
float load_avg_1m = 2;
|
|
}
|
|
|
|
message VacuumVolumeCommitRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VacuumVolumeCommitResponse {
|
|
bool is_read_only = 1;
|
|
uint64 volume_size = 2;
|
|
}
|
|
|
|
message VacuumVolumeCleanupRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VacuumVolumeCleanupResponse {
|
|
}
|
|
|
|
message DeleteCollectionRequest {
|
|
string collection = 1;
|
|
}
|
|
message DeleteCollectionResponse {
|
|
}
|
|
|
|
message AllocateVolumeRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
int64 preallocate = 3;
|
|
string replication = 4;
|
|
string ttl = 5;
|
|
uint32 memory_map_max_size_mb = 6;
|
|
string disk_type = 7;
|
|
uint32 version = 8;
|
|
}
|
|
message AllocateVolumeResponse {
|
|
}
|
|
|
|
message VolumeSyncStatusRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeSyncStatusResponse {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
string replication = 4;
|
|
string ttl = 5;
|
|
uint64 tail_offset = 6;
|
|
uint32 compact_revision = 7;
|
|
uint64 idx_file_size = 8;
|
|
uint32 version = 9;
|
|
}
|
|
|
|
message VolumeIncrementalCopyRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 since_ns = 2;
|
|
}
|
|
message VolumeIncrementalCopyResponse {
|
|
bytes file_content = 1;
|
|
}
|
|
|
|
message VolumeMountRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeMountResponse {
|
|
}
|
|
|
|
message VolumeUnmountRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeUnmountResponse {
|
|
}
|
|
|
|
message VolumeConsolidateIndexRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeConsolidateIndexResponse {
|
|
}
|
|
|
|
message VolumeDeleteRequest {
|
|
uint32 volume_id = 1;
|
|
bool only_empty = 2;
|
|
// when true, do not remove the cloud-tier object backing the volume.
|
|
// used for moves where another server is taking over the same .vif.
|
|
bool keep_remote_data = 3;
|
|
}
|
|
message VolumeDeleteResponse {
|
|
}
|
|
|
|
message VolumeMarkReadonlyRequest {
|
|
uint32 volume_id = 1;
|
|
bool persist = 2;
|
|
}
|
|
message VolumeMarkReadonlyResponse {
|
|
}
|
|
|
|
message VolumeMarkWritableRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeMarkWritableResponse {
|
|
}
|
|
|
|
message VolumeConfigureRequest {
|
|
uint32 volume_id = 1;
|
|
string replication = 2;
|
|
}
|
|
message VolumeConfigureResponse {
|
|
string error = 1;
|
|
}
|
|
|
|
message VolumeStatusRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeStatusResponse {
|
|
bool is_read_only = 1;
|
|
uint64 volume_size = 2;
|
|
uint64 file_count = 3;
|
|
uint64 file_deleted_count = 4;
|
|
}
|
|
|
|
message GetStateRequest {
|
|
}
|
|
message GetStateResponse {
|
|
VolumeServerState state = 1;
|
|
}
|
|
|
|
message SetStateRequest {
|
|
// SetState updates *all* volume server flags at once. Retrieve state with GetState(),
|
|
// modify individual flags as required, then call this RPC to update.
|
|
VolumeServerState state = 1;
|
|
}
|
|
message SetStateResponse {
|
|
VolumeServerState state = 1;
|
|
}
|
|
|
|
message VolumeCopyRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
string replication = 3;
|
|
string ttl = 4;
|
|
string source_data_node = 5;
|
|
string disk_type = 6;
|
|
int64 io_byte_per_second = 7;
|
|
}
|
|
message VolumeCopyResponse {
|
|
uint64 last_append_at_ns = 1;
|
|
int64 processed_bytes = 2;
|
|
}
|
|
|
|
message CopyFileRequest {
|
|
uint32 volume_id = 1;
|
|
string ext = 2;
|
|
uint32 compaction_revision = 3;
|
|
uint64 stop_offset = 4;
|
|
string collection = 5;
|
|
bool is_ec_volume = 6;
|
|
bool ignore_source_file_not_found = 7;
|
|
}
|
|
message CopyFileResponse {
|
|
bytes file_content = 1;
|
|
int64 modified_ts_ns = 2;
|
|
}
|
|
|
|
message ReceiveFileRequest {
|
|
oneof data {
|
|
ReceiveFileInfo info = 1;
|
|
bytes file_content = 2;
|
|
}
|
|
}
|
|
|
|
message ReceiveFileInfo {
|
|
uint32 volume_id = 1;
|
|
string ext = 2;
|
|
string collection = 3;
|
|
bool is_ec_volume = 4;
|
|
uint32 shard_id = 5;
|
|
uint64 file_size = 6;
|
|
uint32 disk_id = 7; // EC shard disk; 0 = auto-select (see VolumeEcShardsCopyRequest.disk_id)
|
|
|
|
// Field numbers 8-11 are reserved for versioned-EC; disk_type stays at 12.
|
|
// Staged-new-volume mode (EC decode onto a clean peer): set on a non-EC push
|
|
// whose volume does not yet exist on this server. The server picks a disk
|
|
// location of this medium with a free slot and writes <base><ext>.copying,
|
|
// finalized by VolumeEcShardsToVolume(from_staged).
|
|
string disk_type = 12;
|
|
}
|
|
|
|
message ReceiveFileResponse {
|
|
uint64 bytes_written = 1;
|
|
string error = 2;
|
|
}
|
|
|
|
message ReadNeedleBlobRequest {
|
|
uint32 volume_id = 1;
|
|
int64 offset = 3; // actual offset
|
|
int32 size = 4;
|
|
}
|
|
message ReadNeedleBlobResponse {
|
|
bytes needle_blob = 1;
|
|
}
|
|
|
|
message ReadNeedleMetaRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 needle_id = 2;
|
|
int64 offset = 3; // actual offset
|
|
int32 size = 4;
|
|
}
|
|
message ReadNeedleMetaResponse {
|
|
uint32 cookie = 1;
|
|
uint64 last_modified = 2;
|
|
uint32 crc = 3;
|
|
string ttl = 4;
|
|
uint64 append_at_ns = 5;
|
|
}
|
|
|
|
message WriteNeedleBlobRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 needle_id = 2;
|
|
int32 size = 3;
|
|
bytes needle_blob = 4;
|
|
}
|
|
message WriteNeedleBlobResponse {
|
|
}
|
|
|
|
message ReadAllNeedlesRequest {
|
|
repeated uint32 volume_ids = 1;
|
|
}
|
|
message ReadAllNeedlesResponse {
|
|
uint32 volume_id = 1;
|
|
uint64 needle_id = 2;
|
|
uint32 cookie = 3;
|
|
bytes needle_blob = 5;
|
|
bool needle_blob_compressed = 6;
|
|
uint64 last_modified = 7;
|
|
uint32 crc = 8;
|
|
bytes name = 9;
|
|
bytes mime = 10;
|
|
}
|
|
|
|
message VolumeTailSenderRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 since_ns = 2;
|
|
uint32 idle_timeout_seconds = 3;
|
|
}
|
|
message VolumeTailSenderResponse {
|
|
bytes needle_header = 1;
|
|
bytes needle_body = 2;
|
|
bool is_last_chunk = 3;
|
|
uint32 version = 4;
|
|
}
|
|
|
|
message VolumeTailReceiverRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 since_ns = 2;
|
|
uint32 idle_timeout_seconds = 3;
|
|
string source_volume_server = 4;
|
|
}
|
|
message VolumeTailReceiverResponse {
|
|
}
|
|
|
|
message VolumeEcShardsGenerateRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
}
|
|
message VolumeEcShardsGenerateResponse {
|
|
}
|
|
|
|
message VolumeEcShardsRebuildRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
bool unsafe_ignore_sidecar = 3; // bypass the bitrot-sidecar fail-closed guard (operator override; distinct from ec.rebuild -force)
|
|
}
|
|
message VolumeEcShardsRebuildResponse {
|
|
repeated uint32 rebuilt_shard_ids = 1;
|
|
}
|
|
|
|
message VolumeEcShardsCopyRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
repeated uint32 shard_ids = 3;
|
|
bool copy_ecx_file = 4;
|
|
string source_data_node = 5;
|
|
bool copy_ecj_file = 6;
|
|
bool copy_vif_file = 7;
|
|
uint32 disk_id = 8; // Target disk ID for storing EC shards
|
|
bool copy_ecsum_file = 9; // copy the bitrot checksum sidecar (.ecsum) when present; tolerant of a missing source (no-op), since this non-2PC path has no Prepare backstop
|
|
}
|
|
message VolumeEcShardsCopyResponse {
|
|
}
|
|
|
|
message VolumeEcShardsDeleteRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
repeated uint32 shard_ids = 3;
|
|
bool full_teardown = 4; // pre-encode cleanup: wipe every EC artifact + generation for this volume, not just shard_ids
|
|
int64 encode_ts_ns = 5; // full_teardown generation fence: delete only a disk whose .vif generation is strictly OLDER than this; preserve same-or-newer, generation 0, and an unreadable .vif. 0 => wipe-all (shell pre-encode / pre-upgrade)
|
|
}
|
|
message VolumeEcShardsDeleteResponse {
|
|
bool full_teardown_done = 1; // set by a new server that performed full_teardown; absent from an old server lets the caller detect the silent no-op
|
|
}
|
|
|
|
message VolumeEcShardsMountRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
repeated uint32 shard_ids = 3;
|
|
string source_disk_type = 4; // disk type of the source volume, applied to the in-memory EC volume so heartbeats report under it (#9423)
|
|
bool recover_missing_index = 5; // first fetch a missing .ecx index from a peer so on-disk shards without a local index become mountable (#10104)
|
|
}
|
|
message VolumeEcShardsMountResponse {
|
|
}
|
|
|
|
message VolumeEcShardsUnmountRequest {
|
|
uint32 volume_id = 1;
|
|
repeated uint32 shard_ids = 3;
|
|
int64 encode_ts_ns = 4; // generation fence: skip a disk whose mounted EC volume is this generation or newer (0 = unfenced, unmount all)
|
|
}
|
|
message VolumeEcShardsUnmountResponse {
|
|
}
|
|
|
|
message VolumeEcShardReadRequest {
|
|
uint32 volume_id = 1;
|
|
uint32 shard_id = 2;
|
|
int64 offset = 3;
|
|
int64 size = 4;
|
|
uint64 file_key = 5;
|
|
reserved 6;
|
|
int64 encode_ts_ns = 7; // caller's expected encode time; the server rejects a shard from a different encode run
|
|
}
|
|
message VolumeEcShardReadResponse {
|
|
bytes data = 1;
|
|
bool is_deleted = 2;
|
|
int64 encode_ts_ns = 3; // identity of the shard actually served; client rejects a mismatch (0 = pre-upgrade server)
|
|
}
|
|
|
|
message VolumeEcBlobDeleteRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
uint64 file_key = 3;
|
|
uint32 version = 4;
|
|
}
|
|
message VolumeEcBlobDeleteResponse {
|
|
}
|
|
|
|
message VolumeEcShardsToVolumeRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
// Staged mode: the caller already decoded the EC shards off-box and pushed
|
|
// .dat/.idx/.vif as <base><ext>.copying to this server (ReceiveFile
|
|
// staged-new-volume mode). Adopt them as a normal volume instead of decoding
|
|
// local EC shards in place, so <vid> is never registered as both EC and
|
|
// normal on one disk.
|
|
bool from_staged = 3;
|
|
string disk_type = 4; // target medium's disk location for the normal volume (staged mode)
|
|
}
|
|
message VolumeEcShardsToVolumeResponse {
|
|
}
|
|
|
|
message VolumeEcShardsInfoRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message VolumeEcShardsInfoResponse {
|
|
repeated EcShardInfo ec_shard_infos = 1;
|
|
uint64 volume_size = 2;
|
|
uint64 file_count = 3;
|
|
uint64 file_deleted_count = 4;
|
|
}
|
|
|
|
message EcShardInfo {
|
|
uint32 shard_id = 1;
|
|
int64 size = 2;
|
|
string collection = 3;
|
|
uint32 volume_id = 4;
|
|
}
|
|
|
|
message ReadVolumeFileStatusRequest {
|
|
uint32 volume_id = 1;
|
|
}
|
|
message ReadVolumeFileStatusResponse {
|
|
uint32 volume_id = 1;
|
|
uint64 idx_file_timestamp_seconds = 2;
|
|
uint64 idx_file_size = 3;
|
|
uint64 dat_file_timestamp_seconds = 4;
|
|
uint64 dat_file_size = 5;
|
|
uint64 file_count = 6;
|
|
uint32 compaction_revision = 7;
|
|
string collection = 8;
|
|
string disk_type = 9;
|
|
VolumeInfo volume_info = 10;
|
|
uint32 version = 11;
|
|
}
|
|
|
|
message DiskStatus {
|
|
string dir = 1;
|
|
uint64 all = 2;
|
|
uint64 used = 3;
|
|
uint64 free = 4;
|
|
float percent_free = 5;
|
|
float percent_used = 6;
|
|
string disk_type = 7;
|
|
string error = 8;
|
|
}
|
|
|
|
message MemStatus {
|
|
int32 goroutines = 1;
|
|
uint64 all = 2;
|
|
uint64 used = 3;
|
|
uint64 free = 4;
|
|
uint64 self = 5;
|
|
uint64 heap = 6;
|
|
uint64 stack = 7;
|
|
}
|
|
|
|
// tired storage on volume servers
|
|
message RemoteFile {
|
|
string backend_type = 1;
|
|
string backend_id = 2;
|
|
string key = 3;
|
|
uint64 offset = 4;
|
|
uint64 file_size = 5;
|
|
uint64 modified_time = 6;
|
|
string extension = 7;
|
|
}
|
|
message VolumeInfo {
|
|
repeated RemoteFile files = 1;
|
|
uint32 version = 2;
|
|
string replication = 3;
|
|
uint32 bytes_offset = 4;
|
|
int64 dat_file_size = 5; // store the original dat file size
|
|
uint64 expire_at_sec = 6; // expiration time of ec volume
|
|
bool read_only = 7;
|
|
EcShardConfig ec_shard_config = 8; // EC shard configuration (optional, null = use default 10+4)
|
|
}
|
|
|
|
// EcShardConfig specifies erasure coding shard configuration
|
|
message EcShardConfig {
|
|
uint32 data_shards = 1; // Number of data shards (e.g., 10)
|
|
uint32 parity_shards = 2; // Number of parity shards (e.g., 4)
|
|
int64 encode_ts_ns = 3; // encode time (unix nanos); a read served from a shard of a different encode run is rejected
|
|
}
|
|
|
|
// EcBitrotProtection is the entire content of a bitrot checksum sidecar
|
|
// (<base>.ecsum for the legacy generation, <base>.ecsum.v<N> for vacuum
|
|
// generation N). On disk it is wrapped in a fixed header carrying a CRC32C
|
|
// over this serialized payload (see weed/storage/erasure_coding/ec_bitrot.go).
|
|
message EcBitrotProtection {
|
|
ChecksumAlgorithm algorithm = 1; // CRC32C (Castagnoli)
|
|
uint32 block_size = 2; // bytes per checksum block; default 16777216 (16 MiB), a power-of-two multiple of 1 MiB
|
|
uint32 generation = 3; // EC vacuum generation these checksums describe (0 = legacy/fresh); must match the sidecar filename version
|
|
EcShardConfig ec_shard_config = 4; // data/parity shard counts at encode time
|
|
repeated EcShardChecksums shards = 5; // one entry per shard id in the active layout
|
|
bytes encode_uuid = 6; // random per-encode identity, for stale-sidecar detection across in-place re-encodes
|
|
}
|
|
|
|
message EcShardChecksums {
|
|
uint32 shard_id = 1; // 0..MaxShardCount-1 (custom EC ratios go up to 32)
|
|
int64 covered_size = 2; // shard byte length these checksums cover (must equal the on-disk shard length)
|
|
bytes block_crc32c = 3; // packed little-endian uint32[] = ceil(covered_size/block_size) entries
|
|
}
|
|
|
|
enum ChecksumAlgorithm {
|
|
CHECKSUM_NONE = 0;
|
|
CHECKSUM_CRC32C = 1;
|
|
}
|
|
message OldVersionVolumeInfo {
|
|
repeated RemoteFile files = 1;
|
|
uint32 version = 2;
|
|
string replication = 3;
|
|
uint32 BytesOffset = 4;
|
|
int64 dat_file_size = 5; // store the original dat file size
|
|
uint64 DestroyTime = 6; // expiration time of ec volume
|
|
bool read_only = 7;
|
|
}
|
|
|
|
// tiered storage
|
|
message VolumeTierMoveDatToRemoteRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
string destination_backend_name = 3;
|
|
bool keep_local_dat_file = 4;
|
|
}
|
|
message VolumeTierMoveDatToRemoteResponse {
|
|
int64 processed = 1;
|
|
float processedPercentage = 2;
|
|
}
|
|
|
|
message VolumeTierMoveDatFromRemoteRequest {
|
|
uint32 volume_id = 1;
|
|
string collection = 2;
|
|
bool keep_remote_dat_file = 3;
|
|
}
|
|
message VolumeTierMoveDatFromRemoteResponse {
|
|
int64 processed = 1;
|
|
float processedPercentage = 2;
|
|
}
|
|
|
|
message VolumeServerStatusRequest {
|
|
|
|
}
|
|
message VolumeServerStatusResponse {
|
|
repeated DiskStatus disk_statuses = 1;
|
|
MemStatus memory_status = 2;
|
|
string version = 3;
|
|
string data_center = 4;
|
|
string rack = 5;
|
|
VolumeServerState state = 6;
|
|
}
|
|
|
|
message VolumeServerLeaveRequest {
|
|
}
|
|
message VolumeServerLeaveResponse {
|
|
}
|
|
|
|
// remote storage
|
|
message FetchAndWriteNeedleRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 needle_id = 2;
|
|
uint32 cookie = 3;
|
|
int64 offset = 4;
|
|
int64 size = 5;
|
|
message Replica {
|
|
string url = 1;
|
|
string public_url = 2;
|
|
int32 grpc_port = 3;
|
|
}
|
|
repeated Replica replicas = 6;
|
|
string auth = 7;
|
|
int32 download_concurrency = 8; // multipart download concurrency if supported by the remote storage client; for S3, 0 = default (5)
|
|
// remote conf
|
|
remote_pb.RemoteConf remote_conf = 15;
|
|
remote_pb.RemoteStorageLocation remote_location = 16;
|
|
}
|
|
message FetchAndWriteNeedleResponse {
|
|
string e_tag = 1;
|
|
}
|
|
|
|
enum VolumeScrubMode {
|
|
UNKNOWN = 0;
|
|
INDEX = 1;
|
|
FULL = 2;
|
|
LOCAL = 3;
|
|
CHECKSUM = 4; // EC only: verify each local shard's raw bytes against the bitrot checksum sidecar
|
|
}
|
|
|
|
message ScrubVolumeRequest {
|
|
VolumeScrubMode mode = 1;
|
|
// optional list of volume IDs to scrub. if empty, all volumes for the server are scrubbed.
|
|
repeated uint32 volume_ids = 2;
|
|
bool mark_broken_volumes_readonly = 3;
|
|
}
|
|
message ScrubVolumeResponse {
|
|
uint64 total_volumes = 1;
|
|
uint64 total_files = 2;
|
|
repeated uint32 broken_volume_ids = 3;
|
|
repeated string details = 4;
|
|
}
|
|
|
|
message ScrubEcVolumeRequest {
|
|
VolumeScrubMode mode = 1;
|
|
// optional list of volume IDs to scrub. if empty, all EC volumes for the server are scrubbed.
|
|
repeated uint32 volume_ids = 2;
|
|
bool force_deleted_needles_check = 3; // FULL mode only; may report false positives when EC indexes disagree
|
|
}
|
|
message ScrubEcVolumeResponse {
|
|
uint64 total_volumes = 1;
|
|
uint64 total_files = 2;
|
|
repeated uint32 broken_volume_ids = 3;
|
|
repeated EcShardInfo broken_shard_infos = 4;
|
|
repeated string details = 5;
|
|
}
|
|
|
|
// select on volume servers
|
|
message QueryRequest {
|
|
repeated string selections = 1;
|
|
repeated string from_file_ids = 2;
|
|
message Filter {
|
|
string field = 1;
|
|
string operand = 2;
|
|
string value = 3;
|
|
}
|
|
Filter filter = 3;
|
|
|
|
message InputSerialization {
|
|
// NONE | GZIP | BZIP2
|
|
string compression_type = 1;
|
|
message CSVInput {
|
|
string file_header_info = 1; // Valid values: NONE | USE | IGNORE
|
|
string record_delimiter = 2; // Default: \n
|
|
string field_delimiter = 3; // Default: ,
|
|
string quote_character = 4; // Default: "
|
|
string quote_escape_character = 5; // Default: "
|
|
string comments = 6; // Default: #
|
|
// If true, records might contain record delimiters within quote characters
|
|
bool allow_quoted_record_delimiter = 7; // default False.
|
|
}
|
|
message JSONInput {
|
|
string type = 1; // Valid values: DOCUMENT | LINES
|
|
}
|
|
message ParquetInput {
|
|
}
|
|
|
|
CSVInput csv_input = 2;
|
|
JSONInput json_input = 3;
|
|
ParquetInput parquet_input = 4;
|
|
}
|
|
InputSerialization input_serialization = 4;
|
|
|
|
message OutputSerialization {
|
|
message CSVOutput {
|
|
string quote_fields = 1; // Valid values: ALWAYS | ASNEEDED
|
|
string record_delimiter = 2; // Default: \n
|
|
string field_delimiter = 3; // Default: ,
|
|
string quote_character = 4; // Default: "
|
|
string quote_escape_character = 5; // Default: "
|
|
}
|
|
message JSONOutput {
|
|
string record_delimiter = 1;
|
|
}
|
|
|
|
CSVOutput csv_output = 2;
|
|
JSONOutput json_output = 3;
|
|
}
|
|
|
|
OutputSerialization output_serialization = 5;
|
|
}
|
|
message QueriedStripe {
|
|
bytes records = 1;
|
|
}
|
|
|
|
message VolumeNeedleStatusRequest {
|
|
uint32 volume_id = 1;
|
|
uint64 needle_id = 2;
|
|
}
|
|
message VolumeNeedleStatusResponse {
|
|
uint64 needle_id = 1;
|
|
uint32 cookie = 2;
|
|
uint32 size = 3;
|
|
uint64 last_modified = 4;
|
|
uint32 crc = 5;
|
|
string ttl = 6;
|
|
}
|
|
|
|
message PingRequest {
|
|
string target = 1; // default to ping itself
|
|
string target_type = 2;
|
|
}
|
|
message PingResponse {
|
|
int64 start_time_ns = 1;
|
|
int64 remote_time_ns = 2;
|
|
int64 stop_time_ns = 3;
|
|
}
|