From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Proxmox Backup Server development discussion
<pbs-devel@lists.proxmox.com>,
Dominik Csapak <d.csapak@proxmox.com>
Subject: Re: [pbs-devel] [PATCH proxmox-backup 5/6] api: admin: datastore: optimize `groups` api call
Date: Fri, 3 Oct 2025 12:18:38 +0200 [thread overview]
Message-ID: <5304f093-fb23-42ad-ab0c-bca839572d73@proxmox.com> (raw)
In-Reply-To: <20251003085045.1346864-7-d.csapak@proxmox.com>
Am 03.10.25 um 10:50 schrieb Dominik Csapak:
> Currently we always touch all files for each snapshot in a group when
> listing them, even though we don't need all that info.
>
> We're only interested in getting either the last finished snapshot
> information, or the last unfinished one (which must the only one in
> normal use, we can't have multiple unfinished snapshots usually)
>
> Instead of getting all the information upgfront, use the snapshot
s/upgfront/upfront/
> iterator of the group to get only the id, sort them by time, and
> use the first we're interested in, getting the snapshot specific info
> only for those we want to check.
>
> In my (admittedly extreme) setup with ~600 groups with ~1000 snapshots
> each, this changes the time this api call needs from ~40s to <1s.
> (on a relatively fast disk).
nice! In the UI we mainly (only?) uses this for gathering the notes of
a group, FWICT?
>
> While at it, lift the restriction of only returning groups with
> snapshots in them, now returning also empty ones.
>
> To keep api compatibility, use a timestamp of 0 for those.
> (no valid backup could have been made at that time anyway)
lazy question: Is this dependent on the previous patches? From a quick
check, it looks like it might be rather independent and one could apply
this one already.
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> src/api2/admin/datastore.rs | 45 +++++++++++++++++++++++--------------
> 1 file changed, 28 insertions(+), 17 deletions(-)
>
> diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
> index 0b133d166..2252dcfa4 100644
> --- a/src/api2/admin/datastore.rs
> +++ b/src/api2/admin/datastore.rs
> @@ -166,36 +166,47 @@ fn backup_group_to_group_list_item(
> return None;
> }
>
> - let snapshots = match group.list_backups() {
> - Ok(snapshots) => snapshots,
> + let mut snapshots: Vec<_> = match group.iter_snapshots() {
> + Ok(snapshots) => snapshots.collect::<Result<Vec<_>, Error>>().ok()?,
> Err(_) => return None,
> };
>
> let backup_count: u64 = snapshots.len() as u64;
> - if backup_count == 0 {
> - return None;
> - }
> + let last = if backup_count == 1 {
> + // we may have only one unfinished snapshot
> + snapshots.pop().and_then(|dir| BackupInfo::new(dir).ok())
> + } else {
> + // we either have no snapshots, or at least one finished one, since we cannot have
> + // multiple unfinished ones
> + snapshots.sort_by_key(|b| std::cmp::Reverse(b.backup_time()));
> + snapshots
> + .iter()
> + .filter_map(|backup| match BackupInfo::new(backup.clone()) {
> + Ok(info) => {
> + if info.is_finished() {
> + Some(info)
> + } else {
> + None
> + }
> + }
> + Err(_) => None,
nit: Could be written as a bit more concise way:
snapshots
.iter()
.filter_map(|backup| BackupInfo::new(backup.clone()).ok())
.filter(|info| info.is_finished())
.next()
With splitting the conversion to BackupInfo and filtering for finished
backups into two makes it a bit easier (or rather quicker) to follow to me.
> + })
> + .next()
> + };
>
> - let last_backup = snapshots
> - .iter()
> - .fold(&snapshots[0], |a, b| {
> - if a.is_finished() && a.backup_dir.backup_time() > b.backup_dir.backup_time() {
> - a
> - } else {
> - b
> - }
> - })
> - .to_owned();
> + let (last_backup, files) = last
> + .map(|info| (info.backup_dir.backup_time(), info.files))
> + .unwrap_or((0, Vec::new()));
>
> let notes_path = datastore.group_notes_path(ns, group.as_ref());
> let comment = file_read_firstline(notes_path).ok();
>
> let item = GroupListItem {
> backup: group.into(),
> - last_backup: last_backup.backup_dir.backup_time(),
> + last_backup,
> owner: Some(owner),
> backup_count,
> - files: last_backup.files,
> + files,
> comment,
> };
>
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2025-10-03 10:18 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-03 8:50 [pbs-devel] [PATCH proxmox{, -backup} 0/7] introduce streaming content " Dominik Csapak
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox 1/1] pbs-api-types: add api types for " Dominik Csapak
2025-10-07 8:59 ` Wolfgang Bumiller
2025-10-08 6:41 ` Dominik Csapak
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 1/6] backup: hierarchy: add new can_access_any_namespace_in_range helper Dominik Csapak
2025-10-03 9:52 ` Thomas Lamprecht
2025-10-03 10:10 ` Dominik Csapak
2025-10-03 10:21 ` Thomas Lamprecht
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 2/6] backup: hierarchy: reuse 'NS_PRIVS_OK' for namespace helper Dominik Csapak
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 3/6] api: admin: datastore: refactor BackupGroup to GroupListItem conversion Dominik Csapak
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 4/6] api: admin: datastore: factor out 'get_group_owner' Dominik Csapak
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 5/6] api: admin: datastore: optimize `groups` api call Dominik Csapak
2025-10-03 10:18 ` Thomas Lamprecht [this message]
2025-10-03 10:51 ` Dominik Csapak
2025-10-03 12:37 ` Thomas Lamprecht
2025-10-03 8:50 ` [pbs-devel] [PATCH proxmox-backup 6/6] api: admin: datastore: implement streaming content " Dominik Csapak
2025-10-03 11:55 ` Thomas Lamprecht
2025-10-07 12:51 ` Wolfgang Bumiller
2025-10-07 14:22 ` Thomas Lamprecht
2025-10-07 14:31 ` Wolfgang Bumiller
2025-10-07 15:05 ` Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5304f093-fb23-42ad-ab0c-bca839572d73@proxmox.com \
--to=t.lamprecht@proxmox.com \
--cc=d.csapak@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox