diff --git a/lib/harmony/harmonydb/sql/20230712.sql b/lib/harmony/harmonydb/sql/20230712.sql index c4513a7d7..60e28f528 100644 --- a/lib/harmony/harmonydb/sql/20230712.sql +++ b/lib/harmony/harmonydb/sql/20230712.sql @@ -1,15 +1,20 @@ -create table SectorLocation +create table sectorlocation ( - "miner_id" bigint, - "sector_num" bigint, - "sector_filetype" int, - "storage_id" varchar, - "is_primary" bool, - constraint SectorLocation_pk - primary key ("miner_id", "sector_num", "sector_filetype", "storage_id") + miner_id bigint not null, + sector_num bigint not null, + sector_filetype int not null, + storage_id varchar not null, + is_primary bool, + read_ts timestamp(6), + read_refs int, + write_ts timestamp(6), + write_lock_owner varchar, + constraint sectorlocation_pk + primary key (miner_id, sector_num, sector_filetype, storage_id) ); + create table StorageLocation ( "storage_id" varchar not null diff --git a/storage/paths/db_index.go b/storage/paths/db_index.go index 4563ccae1..7d8fbff47 100644 --- a/storage/paths/db_index.go +++ b/storage/paths/db_index.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/google/uuid" "go.opencensus.io/stats" "go.opencensus.io/tag" "golang.org/x/xerrors" @@ -730,7 +731,7 @@ func isLocked(ts sql.NullTime) bool { return ts.Valid && ts.Time.After(time.Now().Add(-LockTimeOut)) } -func (dbi *DBIndex) lock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) { +func (dbi *DBIndex) lock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType, lockUuid uuid.UUID) (bool, error) { if read|write == 0 { return false, nil } @@ -792,11 +793,14 @@ func (dbi *DBIndex) lock(ctx context.Context, sector abi.SectorID, read storifac // Acquire write locks _, err = dbi.harmonyDB.Exec(ctx, `UPDATE sectorlocation - SET write_ts = NOW() - WHERE miner_id=$1 - AND sector_num=$2 - AND sector_filetype = ANY($3)`, - sector.Miner, sector.Number, write.AllSet()) + SET write_ts = NOW(), write_lock_owner = $1 + WHERE miner_id=$2 + AND sector_num=$3 + AND sector_filetype = ANY($4)`, + lockUuid.String(), + sector.Miner, + sector.Number, + write.AllSet()) if err != nil { return false, xerrors.Errorf("acquiring write locks for sector %v fails with err: %v", sector, err) } @@ -808,7 +812,10 @@ func (dbi *DBIndex) lock(ctx context.Context, sector abi.SectorID, read storifac WHERE miner_id=$1 AND sector_num=$2 AND sector_filetype = ANY($3)`, - sector.Miner, sector.Number, read.AllSet()) + sector.Miner, + sector.Number, + + read.AllSet()) if err != nil { return false, xerrors.Errorf("acquiring read locks for sector %v fails with err: %v", sector, err) } @@ -822,25 +829,101 @@ func (dbi *DBIndex) lock(ctx context.Context, sector abi.SectorID, read storifac return true, nil } +func (dbi *DBIndex) unlock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType, lockUuid uuid.UUID) (bool, error) { + if read|write == 0 { + return false, nil + } + + if read|write > (1<