Adjust storage capacity option (#1891)

- Rename storage-size to storage capacity
- Change type to uint64 to avoid potential wrap around
- Change to MB instead of KB and set default to 2GB
This commit is contained in:
Kim De Mey 2023-11-10 17:16:15 +01:00 committed by GitHub
parent bb88b50298
commit c41d531c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 23 deletions

View File

@ -38,10 +38,8 @@ const
defaultAdminListenAddressDesc = $defaultAdminListenAddress defaultAdminListenAddressDesc = $defaultAdminListenAddress
defaultDataDirDesc = defaultDataDir() defaultDataDirDesc = defaultDataDir()
defaultClientConfigDesc = $(defaultClientConfig.httpUri) defaultClientConfigDesc = $(defaultClientConfig.httpUri)
# 100mb seems a bit smallish we may consider increasing defaults after some defaultStorageCapacity* = 2000'u32 # 2 GB default
# network measurements defaultStorageCapacityDesc* = $defaultStorageCapacity
defaultStorageSize* = uint32(1000 * 1000 * 100)
defaultStorageSizeDesc* = $defaultStorageSize
defaultTableIpLimitDesc* = defaultTableIpLimitDesc* =
$defaultPortalProtocolConfig.tableIpLimits.tableIpLimit $defaultPortalProtocolConfig.tableIpLimits.tableIpLimit
@ -220,12 +218,12 @@ type
# TODO maybe it is worth defining minimal storage size and throw error if # TODO maybe it is worth defining minimal storage size and throw error if
# value provided is smaller than minimum # value provided is smaller than minimum
storageSize* {. storageCapacityMB* {.
desc: "Maximum amount (in bytes) of content which will be stored " & desc: "Maximum amount (in megabytes) of content which will be stored " &
"in the local database." "in the local database."
defaultValue: defaultStorageSize defaultValue: defaultStorageCapacity
defaultValueDesc: $defaultStorageSizeDesc defaultValueDesc: $defaultStorageCapacityDesc
name: "storage-size" .}: uint32 name: "storage-capacity" .}: uint64
trustedBlockRoot* {. trustedBlockRoot* {.
desc: "Recent trusted finalized block root to initialize the consensus light client from. " & desc: "Recent trusted finalized block root to initialize the consensus light client from. " &

View File

@ -53,7 +53,7 @@ type
ContentDB* = ref object ContentDB* = ref object
kv: KvStoreRef kv: KvStoreRef
maxSize: uint32 storageCapacity*: uint64
sizeStmt: SqliteStmt[NoParams, int64] sizeStmt: SqliteStmt[NoParams, int64]
unusedSizeStmt: SqliteStmt[NoParams, int64] unusedSizeStmt: SqliteStmt[NoParams, int64]
vacuumStmt: SqliteStmt[NoParams, void] vacuumStmt: SqliteStmt[NoParams, void]
@ -95,8 +95,10 @@ template expectDb(x: auto): untyped =
x.expect("working database (disk broken/full?)") x.expect("working database (disk broken/full?)")
proc new*( proc new*(
T: type ContentDB, path: string, maxSize: uint32, inMemory = false): T: type ContentDB, path: string, storageCapacity: uint64, inMemory = false):
ContentDB = ContentDB =
doAssert(storageCapacity <= uint64(int64.high))
let db = let db =
if inMemory: if inMemory:
SqStoreRef.init("", "fluffy-test", inMemory = true).expect( SqStoreRef.init("", "fluffy-test", inMemory = true).expect(
@ -135,7 +137,7 @@ proc new*(
ContentDB( ContentDB(
kv: kvStore, kv: kvStore,
maxSize: maxSize, storageCapacity: storageCapacity,
sizeStmt: sizeStmt, sizeStmt: sizeStmt,
unusedSizeStmt: unusedSizeStmt, unusedSizeStmt: unusedSizeStmt,
vacuumStmt: vacuumStmt, vacuumStmt: vacuumStmt,
@ -192,14 +194,14 @@ proc reclaimSpace*(db: ContentDB): void =
db.vacuumStmt.exec().expectDb() db.vacuumStmt.exec().expectDb()
proc size*(db: ContentDB): int64 = proc size*(db: ContentDB): int64 =
## Retrun current size of DB as product of sqlite page_count and page_size ## Return current size of DB as product of sqlite page_count and page_size:
## https://www.sqlite.org/pragma.html#pragma_page_count ## https://www.sqlite.org/pragma.html#pragma_page_count
## https://www.sqlite.org/pragma.html#pragma_page_size ## https://www.sqlite.org/pragma.html#pragma_page_size
## It returns total size of db i.e both data and metadata used to store content ## It returns the total size of db on the disk, i.e both data and metadata
## also it is worth noting that when deleting content, size may lags behind due ## used to store content.
## It is worth noting that when deleting content, the size may lag behind due
## to the way how deleting works in sqlite. ## to the way how deleting works in sqlite.
## Good description can be found in: https://www.sqlite.org/lang_vacuum.html ## Good description can be found in: https://www.sqlite.org/lang_vacuum.html
var size: int64 = 0 var size: int64 = 0
discard (db.sizeStmt.exec do(res: int64): discard (db.sizeStmt.exec do(res: int64):
size = res).expectDb() size = res).expectDb()
@ -208,17 +210,18 @@ proc size*(db: ContentDB): int64 =
proc unusedSize(db: ContentDB): int64 = proc unusedSize(db: ContentDB): int64 =
## Returns the total size of the pages which are unused by the database, ## Returns the total size of the pages which are unused by the database,
## i.e they can be re-used for new content. ## i.e they can be re-used for new content.
var size: int64 = 0 var size: int64 = 0
discard (db.unusedSizeStmt.exec do(res: int64): discard (db.unusedSizeStmt.exec do(res: int64):
size = res).expectDb() size = res).expectDb()
return size return size
proc usedSize*(db: ContentDB): int64 = proc usedSize*(db: ContentDB): int64 =
## Returns the total size of the database (data + metadata) minus the unused
## pages.
db.size() - db.unusedSize() db.size() - db.unusedSize()
proc contentSize*(db: ContentDB): int64 = proc contentSize*(db: ContentDB): int64 =
## Returns total size of content stored in DB ## Returns total size of the content stored in DB.
var size: int64 = 0 var size: int64 = 0
discard (db.contentSizeStmt.exec do(res: int64): discard (db.contentSizeStmt.exec do(res: int64):
size = res).expectDb() size = res).expectDb()
@ -296,9 +299,10 @@ proc put*(
db.put(key, value) db.put(key, value)
# We use real size for our pruning threshold, which means that database file # The used size is used as pruning threshold. This means that the database
# will reach size specified in db.maxSize, and will stay that size thorough # size will reach the size specified in db.storageCapacity and will stay
# node life time, as after content deletion free pages will be re used. # around that size throughout the node's lifetime, as after content deletion
# due to pruning, the free pages will be re-used.
# TODO: # TODO:
# 1. Devise vacuum strategy - after few pruning cycles database can become # 1. Devise vacuum strategy - after few pruning cycles database can become
# fragmented which may impact performance, so at some point in time `VACUUM` # fragmented which may impact performance, so at some point in time `VACUUM`
@ -308,7 +312,7 @@ proc put*(
# with each addition. # with each addition.
let dbSize = db.usedSize() let dbSize = db.usedSize()
if dbSize < int64(db.maxSize): if dbSize < int64(db.storageCapacity):
return PutResult(kind: ContentStored) return PutResult(kind: ContentStored)
else: else:
# TODO Add some configuration for this magic number # TODO Add some configuration for this magic number

View File

@ -129,7 +129,7 @@ proc run(config: PortalConf) {.raises: [CatchableError].} =
let let
db = ContentDB.new(config.dataDir / "db" / "contentdb_" & db = ContentDB.new(config.dataDir / "db" / "contentdb_" &
d.localNode.id.toBytesBE().toOpenArray(0, 8).toHex(), d.localNode.id.toBytesBE().toOpenArray(0, 8).toHex(),
maxSize = config.storageSize) storageCapacity = config.storageCapacityMB * 1_000_000)
portalConfig = PortalProtocolConfig.init( portalConfig = PortalProtocolConfig.init(
config.tableIpLimit, config.tableIpLimit,