Collects and prints statistics about how much data is purgeable in an
sstable. Works only with tombstone_gc = {'mode': 'timeout'};
Can help diagnosing the efficiency (or lack of) tombstone-gc.
128 lines
3.9 KiB
Lua
128 lines
3.9 KiB
Lua
--
|
|
-- Copyright (C) 2025-present ScyllaDB
|
|
--
|
|
-- SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
--
|
|
|
|
-- Print statistics on what how much data is purgeable in the sstable(s).
|
|
--
|
|
-- Assumes tombstone_gc = {'mode': 'timeout'}
|
|
-- gc_grace_seconds is hardcoded below, see the tombstone_gc_grace_seconds variable.
|
|
-- Can be overridden by setting the GC_GRACE_SECONDS environment variable.
|
|
|
|
partition = {total=0, live=0, purgeable=0}
|
|
partitions = {total=0, live=0, purgeable=0}
|
|
rows = {total=0, live=0, purgeable=0}
|
|
cells = {total=0, live=0, purgeable=0}
|
|
tombstones = {total=0, live=0, purgeable=0}
|
|
|
|
now = os.time()
|
|
tombstone_gc_grace_seconds = 1 * 24 * 60 * 60 -- 10 days
|
|
|
|
gc_grace_seconds_env = os.getenv('GC_GRACE_SECONDS')
|
|
if gc_grace_seconds_env then
|
|
tombstone_gc_grace_seconds = gc_grace_seconds_env
|
|
end
|
|
|
|
function handle_tombstone(tomb, stats)
|
|
stats.total = stats.total + 1
|
|
if os.time(tomb.deletion_time) + tombstone_gc_grace_seconds < now then
|
|
stats.purgeable = stats.purgeable + 1
|
|
end
|
|
end
|
|
|
|
function handle_atomic_cell(cell)
|
|
if cell.is_live then
|
|
cells.total = cells.total + 1
|
|
cells.live = cells.live + 1
|
|
else
|
|
handle_tombstone(cell.tombstone, tombstones)
|
|
end
|
|
end
|
|
|
|
function handle_collection(cell)
|
|
if cell.tombstone then
|
|
handle_tombstone(cell.tombstone, tombstones)
|
|
end
|
|
for _, v in ipairs(cell.values) do
|
|
handle_atomic_cell(v.value)
|
|
end
|
|
end
|
|
|
|
function handle_cells(cells, has_live_marker)
|
|
rows.total = rows.total + 1
|
|
partition.total = partition.total + 1
|
|
|
|
total = 0
|
|
live = 0
|
|
purgeable = 0
|
|
|
|
for name, cell in pairs(cells) do
|
|
if cell.type == "collection" then
|
|
handle_collection(cell)
|
|
else
|
|
handle_atomic_cell(cell)
|
|
end
|
|
end
|
|
|
|
if live > 0 or has_live_marker then
|
|
rows.live = rows.live + 1
|
|
partition.live = partition.live + 1
|
|
elseif purgeable == total then
|
|
rows.purgeable = rows.purgeable + 1
|
|
partition.purgeable = partition.purgeable + 1
|
|
else
|
|
-- dead, can be derived from total - (live + purgeable)
|
|
end
|
|
end
|
|
|
|
function consume_sstable_start(sst)
|
|
if sst == nil then
|
|
print("Sstable (combined)")
|
|
else
|
|
print("Sstable " .. sst.filename)
|
|
end
|
|
end
|
|
|
|
function consume_partition_start(ps)
|
|
partitions.total = partitions.total + 1
|
|
partition = {total = 0, live = 0, purgeable = 0}
|
|
if ps.tombstone then
|
|
handle_tombstone(ps.tombstone, tombstones)
|
|
end
|
|
end
|
|
|
|
function consume_static_row(sr)
|
|
handle_cells(sr.cells, false)
|
|
end
|
|
|
|
function consume_clustering_row(cr)
|
|
if cr.tombstone then
|
|
handle_tombstone(cr.tombstone, tombstones)
|
|
handle_tombstone(cr.shadowable_tombstone, tombstones)
|
|
end
|
|
handle_cells(cr.cells, cr.marker and cr.marker.is_live)
|
|
end
|
|
|
|
function consume_range_tombstone_change(rtc)
|
|
if rtc.tombstone then
|
|
handle_tombstone(rtc.tombstone, tombstones)
|
|
end
|
|
end
|
|
|
|
function consume_partition_end()
|
|
if partition.live > 0 then
|
|
partitions.live = partitions.live + 1
|
|
elseif partition.purgeable == partition.total then
|
|
partitions.purgeable = partitions.purgeable + 1
|
|
end
|
|
end
|
|
|
|
function consume_sstable_end()
|
|
print(string.format(" %9s %9s %9s %9s", "total", "live", "dead", "purgeable"))
|
|
print(string.format(" cells %9d %9d %9d %9d", cells.total, cells.live, cells.total - (cells.live + cells.purgeable), cells.purgeable))
|
|
print(string.format(" tombstones %9d %9d %9d %9d", tombstones.total, tombstones.live, tombstones.total - (tombstones.live + tombstones.purgeable), tombstones.purgeable))
|
|
print(string.format(" rows %9d %9d %9d %9d", rows.total, rows.live, rows.total - (rows.live + rows.purgeable), rows.purgeable))
|
|
print(string.format(" partitions %9d %9d %9d %9d", partitions.total, partitions.live, partitions.total - (partitions.live + partitions.purgeable), partitions.purgeable))
|
|
end
|