Hi All,
I’d like to propose a new feature in relation to the --read-data-subset
option of the check command. And I would like to seek some input and feedback from the broader restic community before creating a github issue (and potentially submitting a PR after discussion with the dev team).
The current feature is great for checking a repository in increments, particularly large ones. While this is very flexible in defining how to achieve full coverage of the repository, its not very friendly to the casual user who just wants to check their repo routinely and aim for full coverage of the repo over a given period of time. This is especially true when coupled with the challenges of aligning regular repository checks with scheduling tools such as cron. It’s just not as easy as it could be.
As an example, if I want a repository to be checked in its entirety every week, and execute a subset check daily, then using cron, I need to do something like the following:
00 0 * * * restic -r <repo> check --read-data-subset=`date +\%u`/7
Note, if you are like me, you waste time forgetting that percent is a meta-character, at least in some cron implementations, and for literal use such as with the date command, it needs to be escaped with a backslash.
For a larger repository, I might resort to daily executions with full coverage over a month, which I might add is imprecise using this method due to months having inconsistent numbers of days. A more elaborate method is necessary for this situation, and others.
00 0 * * * restic -r <repo> check --read-data-subset=`date +\%d`/31
Choosing 28 days to ensure, no matter which month of the year, there will be full coverage of the repository each month does not work because 29/28 is invalid input for restic:
Fatal: check flag --read-data-subset=n/t values must be positive integers, and n <= t, e.g. --read-data-subset=1/2
But using 31 to avoid this issue has the downside of missing 1, 2 or 3 subsets on shorter months with 28, 29 or 30 days.
In the spirit of:
Make the simple things easy, and the complicated possible.
What I propose is to add new syntax to the existing --read-data-subset
option that makes it easy for a user to perform routine checks of their repositories. So in addition to the existing syntax of subset-number/total-subsets
, augment this model with check-execution-frequency/check-coverage-frequency
. Here are some concrete examples of what I mean, scheduled with cron:
00 0 * * * restic -r <repo> check --read-data-subset=`date +\%u`/7
# Becomes:
00 0 * * * restic -r <repo> check --read-data-subset=daily/weekly
00 0 * * * restic -r <repo> check --read-data-subset=`date +\%d`/31
# Becomes:
00 0 * * * restic -r <repo> check --read-data-subset=daily/monthly
00 0 1 * * restic -r <repo> check --read-data-subset=`date +\%m`/12
# Becomes:
00 0 1 * * restic -r <repo> check --read-data-subset=monthly/yearly
Plus other combinations that might be useful but difficult without writing elaborate scripts.
00 0 * * mon restic -r <repo> check --read-data-subset=weekly/monthly
00 0 * * * restic -r <repo> check --read-data-subset=daily/2weekly
00 0 * * mon restic -r <repo> check --read-data-subset=weekly/3monthly
00 0 1 * * restic -r <repo> check --read-data-subset=monthly/6monthly
Can you infer the execution frequency and full coverage frequency for the above examples?
The idea is to unburden users with writing code to calculate the correct combination of x/y according to their preferred schedule, and let Restic figure it out for them, according to simple human-expressible frequencies.
So my broader questions to the community are:
-
Have you not implemented regular data check of your repo because of this complexity?
-
Do you use the random selection method (i.e. --read-data-subset=20%) because its too difficult to figure out deterministic checking?
-
Or otherwise, would this feature be useful to you?
On the assumption that there is value in investigating this, I propose the following implementation. I’m interested to hear what the developers think.
When processing values provided to the --read-data-subset
option to the check command, detect the following predefined values, and based on the current date, convert them to their matching x/y counterparts, and continue execution as if the x/y values were provided on the command line.
Frequencies
daily
weekly
monthly
yearly
Where the full coverage frequency can included an optional multiplier, which when omitted, assumes 1. For example:
7daily = every week
2weekly = every fortnight
3monthly = every 3 months
2yearly = every 2 years
1yearly = yearly = every year
I am not considering multipliers for the check execution frequency value because most scheduling tools don’t support such granular execution schedules. For example, using cron, it is not easy to execute a command 2weekly (fortnightly).
So this approach has the benefit of being simple (input parsing and translation). I would be prepared to give this a go, despite having no go programming experience (I’m sure there was a potential pun there somewhere). I have an algorithm that I am happy to share in a technical post, for discussion and feedback from developers.
An alternate approach, that is not my preferred option is to support syntax of the form --read-data-subset=/y
where y is the number of check executions necessary for full coverage, and an execution counter is incremented upon each completed check invocation within the repository config file. So the repository would track the last subset check that was completed, so it knows which subset to check on the next, and each subsequent execution thereafter. The repo is exclusively locked during a check, and so the config file could be written to with the incremented subset upon successful completion of a subset check.
This type of solution might be useful when checks aren’t performed on a fixed routine, but rather at opportunistic times, such as when a repository is detected as quiescent. It would also have the benefit of not missing any subsets, due to execution scheduling failure or interrupted checks. The missed subset would simply be checked on the next invocation of the check.
Still, this approach would be a little more invasive, and only worthwhile if there were sufficient interest.
Thoughts?