Commit Graph

7914 Commits

Author SHA1 Message Date
Jakob Borg
21ad99c80a Revert "chore(db): update schema version in the same transaction as migration (#10321)"
This reverts commit 4459438245.
2025-08-31 12:43:41 +02:00
Jakob Borg
4ad3f07691 chore(db): migration for previous commits (#10319)
Recreate the blocks and block lists tables.

---------

Co-authored-by: bt90 <btom1990@googlemail.com>
2025-08-31 09:27:33 +02:00
Simon Frei
4459438245 chore(db): update schema version in the same transaction as migration (#10321)
Just to be entirely sure that if the migration succeeds the schema
version is always also updated. Currently if a migration succeeds but a
later migration doesn't, the changes of the migration apply but the
version stays - if the migration is breaking/non-idempotent, it will
fail when it tries to rerun it next time (otherwise it's just a
pointless re-execution).

Unfortunately with the current `db.runScripts` it wasn't that easy to
do, so I had to do quite a bit of refactoring. I am also ensuring the
right order of transactions now, though I assume that was already the
case lexicographically - can't hurt to be safe.
2025-08-30 13:18:31 +02:00
Jakob Borg
2306c6d989 chore(db): benchmark output, migration blocks/s output (#10320)
Just minor tweaks
2025-08-29 14:58:38 +00:00
Tomasz Wilczyński
0de55ef262 chore(gui): use step of 3600 for versions cleanup interval (#10317)
Currently, the input field has no step defined, meaning that it can be
increased with the arrow keys by the default value of "1". Considering
the fact that the default value is "3600" (seconds or one hour), it is
unlikely that the user wants to change it with such minimal steps.

For this reason, change the default step to "3600" (one hour). If the
user needs more granual control, they can still input the value
in seconds manually.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2025-08-29 15:57:27 +02:00
Tomasz Wilczyński
d083682418 chore(gui): use steps of 1024 KiB for bandwidth rate limits (#10316)
Currently, the bandwidth limit input fields have no step defined, and as
such they use the default value of "1". Taking into account the fact
that these fields use KiB as their measurements, it makes more sense to
use larger steps, such as "1024" (1 MiB), as in most cases, it is very
unlikely that the user needs to have byte-level control over the limits.

Note that these steps only apply to increasing the values by using the
arrow keys, and the user is still allowed to input any value they want
manually.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2025-08-29 15:56:55 +02:00
Jakob Borg
c918299eab refactor(db): slightly improve insert performance (#10318)
This just removes an unnecessary foreign key constraint, where we
already do the garbage collection manually in the database service.
However, as part of getting here I tried a couple of other variants
along the way:

- Changing the order of the primary key from `(hash, blocklist_hash,
idx)` to `(blocklist_hash, idx, hash)` so that inserts would be
naturally ordered. However this requires a new index `on blocks (hash)`
so that we can still look up blocks by hash, and turns out to be
strictly worse than what we already have.
- Removing the primary key entirely and the `WITHOUT ROWID` to make it a
rowid table without any required order, and an index as above. This is
faster when the table is small, but becomes slower when it's large (due
to dual indexes I guess).

These are the benchmark results from current `main`, the second
alternative below ("Index(hash)") and this proposal that retains the
combined primary key ("combined"). Overall it ends up being about 65%
faster.

<img width="764" height="452" alt="Screenshot 2025-08-29 at 14 36 28"
src="https://github.com/user-attachments/assets/bff3f9d1-916a-485f-91b7-b54b477f5aac"
/>

Ref #10264
2025-08-29 15:26:23 +02:00
bt90
b59443f136 chore(db): avoid rowid for blocks and blocklists (#10315)
### Purpose

Noticed "large" autgenerated indices on blocks and blocklists in
https://forum.syncthing.net/t/database-or-disk-is-full-might-be-syncthing-might-be-qnap/24930/7

They both have a primary key and don't need rowids

## Authorship

Your name and email will be added automatically to the AUTHORS file
based on the commit metadata.
2025-08-29 11:12:39 +02:00
Tomasz Wilczyński
7189a3ebff fix(model): consider number of CPU cores when calculating hashers on interactive OS (#10284) (#10286)
Currently, the number of hashers is always set to 1 on interactive
operating systems, which are defined as Windows, macOS, iOS, and
Android. However, with modern multicore CPUs, it does not make much
sense to limit performance so much.

For example, without this fix, a CPU with 16 cores / 32 threads is
still limited to using just a single thread to hash files per folder,
which may severely affect its performance.

For this reason, instead of using a fixed value, calculate the number
dynamically, so that it equals one-fourth of the total number of CPU
cores. This way, the value of hashes will still end up being just 1 on
a slower 4-thread CPU, but it will be allowed to take larger values when
the number of threads is higher, increasing hashing performance in the
process.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2025-08-26 10:04:08 +00:00
Tomasz Wilczyński
6ed4cca691 fix(model): consider MaxFolderConcurrency when calculating number of hashers (#10285)
Currently, the number of hashers, with the exception of some specific
operating systems or when defined manually, equals the number of CPU
cores divided by the overall number of folders, and it does not take
into account the value of MaxFolderConcurrency at all. This leads to
artificial performance limits even when MaxFolderConcurrency is set to
values lower than the number of cores.

For example, let's say that the number of folders is 50 and
MaxFolderConcurrency is set a value of 4 on a 16-core CPU. With the old
calculation, the number of hashers would still end up being just 1 due
to the large number of folders. However, with the new calculation, the
number of hashers in this case will be 4, leading to better hashing
performance per folder.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2025-08-26 11:33:58 +02:00
Tommy van der Vorst
958f51ace6 fix(cmd): only start temporary API server during migration if it's enabled (#10284) 2025-08-25 05:46:23 +00:00
Syncthing Release Automation
07f1320e00 chore(gui, man, authors): update docs, translations, and contributors 2025-08-25 03:57:29 +00:00
Jakob Borg
3da449cfa3 chore(ursrv): count database engines 2025-08-24 22:35:00 +02:00
Jakob Borg
655ef63c74 chore(ursrv): separate calculation from serving metrics 2025-08-24 22:34:58 +02:00
Jakob Borg
01257e838b build: use Go 1.24 tools pattern (#10281) 2025-08-24 12:17:20 +00:00
Simon Frei
e54f51c9c5 chore(db): cleanup DB in tests and remove OpenTemp (#10282)
Filled up my tmpfs with test DBs when running benchmarks :)
2025-08-24 09:58:56 +00:00
Simon Frei
a259a009c8 chore(db): adjust db bench name to improve benchstat grouping (#10283)
The benchstat tool allows custom grouping when comparing with what it
calls "sub-name configuration keys":

https://pkg.go.dev/golang.org/x/perf@v0.0.0-20250813145418-2f7363a06fe1/cmd/benchstat#hdr-Configuring_comparisons

That's quite useful for these benchmarks, as we basically have two
independent configs: The type of benchmark and the size. Real example
usage for the prepared named statements PR (results are rubbish for
unrelated reasons):

```
$ benchstat -row ".name /n" bench-main.out bench-prepared.out
goos: linux
goarch: amd64
pkg: github.com/syncthing/syncthing/internal/db/sqlite
cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
                            │ bench-main-20250823_014059.out │   bench-prepared-20250823_022849.out   │
                            │             sec/op             │     sec/op      vs base                │
Update Insert100Loc                           248.5m ±  8% ¹   157.7m ±  7% ¹  -36.54% (p=0.000 n=50)
Update RepBlocks100                           253.7m ±  4% ¹   163.6m ±  7% ¹  -35.49% (p=0.000 n=50)
Update RepSame100                            130.42m ±  3% ¹   60.26m ±  2% ¹  -53.80% (p=0.000 n=50)
Update Insert100Rem                           38.54m ±  5% ¹   21.94m ±  1% ¹  -43.07% (p=0.000 n=50)
Update GetGlobal100                          10.897m ±  4% ¹   4.231m ±  1% ¹  -61.17% (p=0.000 n=50)
Update LocalSequenced                         7.560m ±  5% ¹   3.124m ±  2% ¹  -58.68% (p=0.000 n=50)
Update GetDeviceSequenceLoc                  17.554µ ±  6% ¹   8.400µ ±  1% ¹  -52.15% (n=50)
Update GetDeviceSequenceRem                  17.727µ ±  4% ¹   8.237µ ±  2% ¹  -53.54% (p=0.000 n=50)
Update RemoteNeed                              4.147 ± 77% ¹    1.903 ± 78% ¹  -54.11% (p=0.000 n=50)
Update LocalNeed100Largest                   21.516m ± 22% ¹   9.312m ± 47% ¹  -56.72% (p=0.000 n=50)
geomean                                       15.35m           7.486m          -51.22%
¹ benchmarks vary in .fullname
```
2025-08-23 16:12:55 +02:00
Jakob Borg
8151bcddff fix(db): clean files for dropped folders at startup (#10280)
This adds a cleanup stage to remove database files for folders that no
longer exist on startup. Folder database files were already removed when
dropping a folder, assuming that the folder database had been opened at
that point. This won't be the case though when a folder is removed from
the config when Syncthing isn't running, or when a folder is dropped and
re-migrated in a restarted migration.
v2.0.3
2025-08-22 09:00:05 +02:00
Jakob Borg
d776657b52 fix(cmd): provide temporary GUI/API server during database migration (#10279)
This adds a temporary GUI/API server during the database migration. It
responds with 200 OK and some log output for every request. This serves
two purposes:
- Primarily, for deployments that use the API as a health check, it
gives them something positive to accept during the migration, reducing
the risk of the migration getting killed halfway through and restarted,
thus never completing.
- Secondarily, it gives humans who happen to try to load the GUI some
sort of indication of what's going on.

Obviously, anything that expects a well-formed API response at this
stage is still going to fail. They were already failing though, as we
didn't even listen at this point before.
2025-08-22 08:35:42 +02:00
Jakob Borg
0416103f26 fix(cmd): make database migration more robust to write errors (#10278)
Two things:
- We could run into a write error, which would block the progress
forever without an error. This because the writer routine exited, while
the reader was just blocked on sending to it.
- After a failed migration, inserts could fail with unique index
constraint errors because we are reusing the sequence numbers from the
original database. Add a drop folder to the start of migration to handle
this.

Additionally, the drop folder will clear out broken database files due
to killed migrations.
2025-08-22 08:08:06 +02:00
Jakob Borg
7bfcdfb577 build: downgrade gopsutil (fixes #10276) (#10277) 2025-08-21 20:09:31 +00:00
Jakob Borg
e6a9b09527 fix: permissions in moving deb files? 2025-08-20 23:32:32 +02:00
Jakob Borg
c8f52ba1bc build: use new apt publisher 2025-08-20 23:05:52 +02:00
Ross Smith II
3058aa6315 chore(slog): re-enable LOGGER_DISCARD (fixes #10262) (#10267)
### Purpose

Re-enables LOGGER_DISCARD. See #10262.

### Documentation

No changes needed, as the docs already mention this variable.
2025-08-19 22:36:10 +02:00
André Colomb
60160db23a fix(cmd): restore --version flag for compatibility (#10269)
### Purpose

This was lost / replaced when introducing the "version" command.
However, the documentation still lists the flag - actually under the
serve command, but that can be omitted. Common convention for CLI
programs is to accept it as a flag.

### Testing

```
$ bin/syncthing --help
Usage: syncthing <command> [flags]

Flags:
  -h, --help           Show context-sensitive help.
  -C, --config=PATH    Set configuration directory (config and keys) ($STCONFDIR)
  -D, --data=PATH      Set data directory (database and logs) ($STDATADIR)
  -H, --home=PATH      Set configuration and data directory ($STHOMEDIR)
      --version        Show current version, then exit

Commands:
  serve                  Run Syncthing (default)
  cli                    Command line interface for Syncthing
  browser                Open GUI in browser, then exit
  decrypt                Decrypt or verify an encrypted folder
  device-id              Show device ID, then exit
  generate               Generate key and config, then exit
  paths                  Show configuration paths, then exit
  upgrade                Perform or check for upgrade, then exit
  version                Show current version, then exit
  debug                  Various debugging commands
  install-completions    Print commands to install shell completions

Run "syncthing <command> --help" for more information on a command.
```

```
$ bin/syncthing --version
syncthing v2.0.3-dev.2.g0f47e944-restore-version-flag "Hafnium Hornet" (go1.24.0 linux-amd64) acolomb@riddo 2025-08-18 19:25:31 UTC
```

### Documentation

Already / *still* listed in the docs under Command Line Operation.
2025-08-18 22:00:03 +02:00
Syncthing Release Automation
66b28e9aed chore(gui, man, authors): update docs, translations, and contributors 2025-08-18 04:05:25 +00:00
Jakob Borg
755daaa7b7 build: set netgo & osusergo tags for Linux build (#10261)
Avoid:

/_/GOROOT/src/os/user/cgo_lookup_cgo.go:45:(.text+0x54): warning: Using
'getgrgid_r' in statically linked applications requires at runtime the
shared libraries from the glibc version used for linking

and

/tmp/go-build/cgo-gcc-prolog:60:(.text+0x40): warning: Using
'getaddrinfo' in statically linked applications requires at runtime the
shared libraries from the glibc version used for linking
v2.0.2
2025-08-16 06:33:01 +02:00
Jakob Borg
33b5c3c62e build: bump required language level to 1.24, compiler to 1.25 (#10248)
(After 2.0.1)
2025-08-16 06:02:58 +02:00
Jakob Borg
ffb30392e8 build: remove netgo and osusergo build tags (fixes #10251) (#10256)
I added these tags as part of the big database PR, but I forget why. I
think it came from an attempt at a static binary using the Go-based
SQLite packages, but that's not the primary build anymore anyway. We can
remove this and go back to the standard resolvers, which gives better
support for primarily Windows and macOS special resolution methods...
2025-08-14 21:32:06 +02:00
Jakob Borg
7a76685d7e fix: increase default delete retention to 15 months (#10252)
365 + 90 days = 10920h.

Also, actually enforce the minimum interval of 24h.
v2.0.1
2025-08-14 08:15:53 +02:00
Jakob Borg
370bbb8f26 fix(db): handle path names that include URL special chars (fixes #10245) (#10247)
😬
2025-08-13 13:01:16 +02:00
Jakob Borg
9ea6c9c3c3 fix(etc): correct incantation to launch browser in Linux desktop file (#10246) 2025-08-13 09:56:58 +02:00
Jakob Borg
8f117a4417 build(deps): update (most) dependencies (#10243)
- Except jackpal/gateway which would bump Go
- Except quic-go which had some API change 
- While rebasing the patch on go-sqlite3
2025-08-12 22:34:40 +02:00
Ross Smith II
bbf48ae334 fix(all): various typos (#10242) 2025-08-12 20:05:10 +02:00
Jakob Borg
fcf4916086 fix: allow upgrade without config dir (fixes #10240) (#10241) 2025-08-12 18:44:57 +02:00
Jakob Borg
5d8033343f chore: repo mirror job v2.0.0 2025-08-11 22:16:10 +02:00
Jakob Borg
c74d2a9872 chore: update man pages for 2.0 v2.0.0-rc.25 2025-08-11 19:33:32 +02:00
Jakob Borg
3da84804b6 build: just special case stable-v2 for Debian for now 2025-08-11 19:17:33 +02:00
Jakob Borg
5b75c6ddcb build: split apt archive into major version generations 2025-08-11 18:57:18 +02:00
Syncthing Release Automation
ae03854575 chore(gui, man, authors): update docs, translations, and contributors 2025-08-11 04:06:30 +00:00
tomasz1986
ad196173d0 chore(gui): remove redundant "authenticated" conditions from Actions menu (#10235) (#10237)
chore(gui): remove redundant "authenticated" conditions from Actions
menu (#10235)

Due to previous code changes, the whole Actions menu is only available
when the user is logged in. As such, there is no reason to have the same
ng-if="authenticated" condition repeated in other items belonging to it.

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>

Signed-off-by: Tomasz Wilczyński <twilczynski@naver.com>
2025-08-10 22:13:53 +02:00
Jakob Borg
d682220305 chore: remove GUI "debugging" toggle, debug HTTP metrics (#10235)
This removes the `debugging` bool under GUI configuration, and two no
longer relevant development endpoints: `httpmetrics` (which I can't
imagine anyone using for anything -- if we need such metrics today, the
right place is the Prometheus exported metrics) and the `peerCompletion`
endpoint (previously used by integration tests).

The debugging bool initially enabled just those two endpoints, which are
not for end users. Then we added profiling and support bundles, which
are very useful indeed for end users to access, and they were hidden
behind the same debug flag. I don't see any reason for keeping that flag
now that these methods are more generally useful.

https://github.com/syncthing/docs/pull/949
2025-08-10 21:14:25 +02:00
Jakob Borg
29e10e00d2 chore(slogutil): ensure quoting of empty and confusing log values (#10236)
Clearer parsing (also for humans)
2025-08-10 08:23:23 +00:00
Jakob Borg
34f61ce464 fix: correct logging of our ID after startup & generate (#10234)
This is one place we actually want the full string.
2025-08-10 06:25:13 +00:00
Ross Smith II
adcbd31e62 fix(test): remove lib/logger from testmocks target (#10231) 2025-08-09 09:56:37 +02:00
Jakob Borg
431da839cf fix(slogutil): quote values with parentheses in them (#10229)
Avoids an obvious parsing ambiguity in log lines.
v2.0.0-rc.24
2025-08-07 09:47:50 +00:00
Jakob Borg
836045ee87 feat: switch logging framework (#10220)
This updates our logging framework from legacy freetext strings using
the `log` package to structured log entries using `log/slog`. I have
updated all INFO or higher level entries, but not yet DEBUG (😓)... So,
at a high level:

There is a slight change in log levels, effectively adding a new warning
level:

- DEBUG is still debug (ideally not for users but developers, though
this is something we need to work on)
- INFO is still info, though I've added more data here, effectively
making Syncthing more verbose by default (more on this below)
- WARNING is a new log level that is different from the _old_ WARNING
(more below)
- ERROR is what was WARNING before -- problems that must be dealt with,
and also bubbled as a popup in the GUI.

A new feature is that the logging level can be set per package to
something other than just debug or info, and hence I feel that we can
add a bit more things into INFO while moving some (in fact, most)
current INFO level warnings into WARNING. For example, I think it's
justified to get a log of synced files in INFO and sync failures in
WARNING. These are things that have historically been tricky to debug
properly, and having more information by default will be useful to many,
while still making it possible get close to told level of inscrutability
by setting the log level to WARNING. I'd like to get to a stage where
DEBUG is never necessary to just figure out what's going on, as opposed
to trying to narrow down a likely bug.

Code wise:

- Our logging object, generally known as `l` in each package, is now a
new adapter object that provides the old API on top of the newer one.
(This should go away once all old log entries are migrated.) This is
only for `l.Debugln` and `l.Debugf`.
- There is a new level tracker that keeps the log level for each
package.
- There is a nested setup of handlers, since the structure mandated by
`log/slog` is slightly convoluted (imho). We do this because we need to
do formatting at a "medium" level internally so we can buffer log lines
in text format but with separate timestamp and log level for the API/GUI
to consume.
- The `debug` API call becomes a `loglevels` API call, which can set the
log level to `DEBUG`, `INFO`, `WARNING` or `ERROR` per package. The GUI
is updated to handle this.
- Our custom `sync` package provided some debugging of mutexes quite
strongly integrated into the old logging framework, only turned on when
`STTRACE` was set to certain values at startup, etc. It's been a long
time since this has been useful; I removed it.
- The `STTRACE` env var remains and can be used the same way as before,
while additionally permitting specific log levels to be specified,
`STTRACE=model:WARN,scanner:DEBUG`.
- There is a new command line option `--log-level=INFO` to set the
default log level.
- The command line options `--log-flags` and `--verbose` go away, but
are currently retained as hidden & ignored options since we set them by
default in some of our startup examples and Syncthing would otherwise
fail to start.

Sample format messages:

```
2009-02-13 23:31:30 INF A basic info line (attr1="val with spaces" attr2=2 attr3="val\"quote" a=a log.pkg=slogutil)
2009-02-13 23:31:30 INF An info line with grouped values (attr1=val1 foo.attr2=2 foo.bar.attr3=3 a=a log.pkg=slogutil)
2009-02-13 23:31:30 INF An info line with grouped values via logger (foo.attr1=val1 foo.attr2=2 a=a log.pkg=slogutil)
2009-02-13 23:31:30 INF An info line with nested grouped values via logger (bar.foo.attr1=val1 bar.foo.attr2=2 a=a log.pkg=slogutil)
2009-02-13 23:31:30 WRN A warning entry (a=a log.pkg=slogutil)
2009-02-13 23:31:30 ERR An error (a=a log.pkg=slogutil)
```

---------

Co-authored-by: Ross Smith II <ross@smithii.com>
2025-08-07 11:19:36 +02:00
Ross Smith II
49462448d0 feat(ignore): add .stignore escaping on Windows (#10205)
Based on the discussion in
https://forum.syncthing.net/t/towards-syncthing-2-0/24072/35 This PR
adds the ability for Windows users to use the pipe character (|) to
escape the metacharacters *, ?, [, and { in .stignore files.

Additionally, this PR adds the ability for the user to set the escape
character to backslash, or any character they want, by adding a line in
the form:

  #escape=X

(where X is any single rune), to the top of an .stignore file.

This would allow users to use the same .stignore file across platforms,
by simply adding

  #escape=\

to the top of the file.

### Testing

All tests pass in CI.

### Documentation

See https://github.com/syncthing/docs/pull/919

Fixes #10057: Support escaping in .stignore files on Windows
Fixes #7547: Ignore pattern with \[ and \] does not work
2025-08-05 09:55:39 +00:00
Jakob Borg
e3424ad503 fix(model): properly set folder state "syncing" when copying data (#10227)
Prior to this fix, the folder would only get marked as "syncing" once we
started downloading data from the network. However in some cases there
will be a lot of data that can be reused locally and we spend
significant time copying blocks before downloading anything; in that
case, the folder would appear as "preparing to sync" while it was in
fact moving lots of data.

This fixes that, making it "syncing" as soon as it begins either copying
or downloading data.
2025-08-05 09:47:44 +00:00
Syncthing Release Automation
5703423c00 chore(gui, man, authors): update docs, translations, and contributors 2025-08-04 04:11:16 +00:00