Error: The socket has been shut down

Turning off the warning would be an example. It might be undocumented because it can be dangerous.

You could certainly start from scratch without nuking old, while we’re seeing if the current one is fixable.
AFAIK Backblaze doesn’t charge for uploads, and there’s no minimum retention, so cost should be low.

You shouldn’t be doing anything until file upload works though. I suppose you could test on a small new backup, but finding and running BackendTester may be simpler. Either way, don’t make situation worse.

Deleting is the typical approach when the network + destination is working, but yours was not as of 6/1.

Fix the network first. After that, it’s still a maybe, but I guess the worst it can do is prove need to restart.

the database. Like I said already, the database internal consistency is tested before every backup. So if on say 19 May Duplicati has done a backup, it has tested the fileset from 18 May (it tests all filesets of course). At this point the fileset was correct else you would have got an error. There is no reason for the data about a fileset in the database to change (unless you use the Duplicati ‘delete’ function now that I think of it). But if you delete a file on your source disk, the fileset should not change (that’s a backup).
So if it’s not consistent now, something very wrong must have happened.

The bug report shows 261397 rows for FilesetID =1415. You can look at the DB backup from sometime before uploads began failing, to compare that, e.g. in DB Browser for SQLite or some other SQLite tool.

My guess is that the FilesetEntry table did not change, but something made the computed “found” drop.
Figuring it out precisely may be impossible without a log, but at least I can see if DB query gets 261396.

Calculated (a.k.a. found) is 261396, based on query from profiling log, adjusting it for FilesetID 1415.

SELECT COUNT(*) FROM (SELECT DISTINCT "Path" FROM (
SELECT
    "L"."Path", 
    "L"."Lastmodified", 
    "L"."Filelength", 
    "L"."Filehash", 
    "L"."Metahash", 
    "L"."Metalength",
    "L"."BlocklistHash", 
    "L"."FirstBlockHash",
    "L"."FirstBlockSize",
    "L"."FirstMetaBlockHash",
    "L"."FirstMetaBlockSize",
    "M"."Hash" AS "MetaBlocklistHash"
FROM
    (
    SELECT 
        "J"."Path", 
        "J"."Lastmodified", 
        "J"."Filelength", 
        "J"."Filehash", 
        "J"."Metahash", 
        "J"."Metalength",
        "K"."Hash" AS "BlocklistHash", 
        "J"."FirstBlockHash",
        "J"."FirstBlockSize",
        "J"."FirstMetaBlockHash",
        "J"."FirstMetaBlockSize",
        "J"."MetablocksetID"
    FROM 
        (
        SELECT 
	        "A"."Path" AS "Path", 
	        "D"."Lastmodified" AS "Lastmodified", 
	        "B"."Length" AS "Filelength", 
	        "B"."FullHash" AS "Filehash", 
	        "E"."FullHash" AS "Metahash", 
	        "E"."Length" AS "Metalength",
	        "A"."BlocksetID" AS "BlocksetID",
	        "F"."Hash" AS "FirstBlockHash",
	        "F"."Size" AS "FirstBlockSize",
	        "H"."Hash" AS "FirstMetaBlockHash",
	        "H"."Size" AS "FirstMetaBlockSize",
	        "C"."BlocksetID" AS "MetablocksetID"
        FROM 
	        "FixedFile" A	
        LEFT JOIN "Blockset" B
          ON "A"."BlocksetID" = "B"."ID" 
        LEFT JOIN "Metadataset" C  
          ON "A"."MetadataID" = "C"."ID"
        LEFT JOIN "FilesetEntry" D
          ON "A"."ID" = "D"."FileID"
        LEFT JOIN "Blockset" E
          ON "E"."ID" = "C"."BlocksetID"
        LEFT JOIN "BlocksetEntry" G
          ON "B"."ID" = "G"."BlocksetID"
        LEFT JOIN "Block" F 
          ON "G"."BlockID" = "F"."ID"  
        LEFT JOIN "BlocksetEntry" I
          ON "E"."ID" = "I"."BlocksetID"
        LEFT JOIN "Block" H 
          ON "I"."BlockID" = "H"."ID"
        WHERE 
          "A"."BlocksetId" >= 0 AND
          "D"."FilesetID" = 1415 AND
          ("I"."Index" = 0 OR "I"."Index" IS NULL) AND  
          ("G"."Index" = 0 OR "G"."Index" IS NULL)
        ) J
    LEFT OUTER JOIN 
        "BlocklistHash" K 
    ON 
        "K"."BlocksetID" = "J"."BlocksetID" 
    ORDER BY "J"."Path", "K"."Index"
    ) L

LEFT OUTER JOIN
    "BlocklistHash" M
ON
    "M"."BlocksetID" = "L"."MetablocksetID"
) UNION SELECT DISTINCT "Path" FROM (
SELECT
    "G"."BlocksetID",
    "G"."ID",
    "G"."Path",
    "G"."Length",
    "G"."FullHash",
    "G"."Lastmodified",
    "G"."FirstMetaBlockHash",
    "H"."Hash" AS "MetablocklistHash"
FROM
    (
    SELECT
        "B"."BlocksetID",
        "B"."ID",
        "B"."Path",
        "D"."Length",
        "D"."FullHash",
        "A"."Lastmodified",
        "F"."Hash" AS "FirstMetaBlockHash",
        "C"."BlocksetID" AS "MetaBlocksetID"
    FROM
        "FilesetEntry" A, 
        "FixedFile" B, 
        "Metadataset" C, 
        "Blockset" D,
        "BlocksetEntry" E,
        "Block" F
    WHERE 
        "A"."FileID" = "B"."ID" 
        AND "B"."MetadataID" = "C"."ID" 
        AND "C"."BlocksetID" = "D"."ID" 
        AND "E"."BlocksetID" = "C"."BlocksetID"
        AND "E"."BlockID" = "F"."ID"
        AND "E"."Index" = 0
        AND ("B"."BlocksetID" = -100 OR "B"."BlocksetID" = -200) 
        AND "A"."FilesetID" = 1415
    ) G
LEFT OUTER JOIN
   "BlocklistHash" H
ON
   "H"."BlocksetID" = "G"."MetaBlocksetID"
ORDER BY
   "G"."Path", "H"."Index"

))

The query is multi-purpose, and far more than needed to get a count, so next step might be to simplify.
You can see that it’s looking at lots of things though, and one of those things may have changed lately.

I just remembered that you posted about doing a database backup. So it should be possible to get back at an earlier database (restored at a different location of course) and try to launch the same query on it. Could be interesting.

Sorry, I thought I understood that the front-end “Test Connection” was doing the same thing as BackendTester.exe, so I wasn’t concerned with trying to get that working.

What would be the path in a Docker containter? I’m using the Linuxserver container.

edit: I found it. Here are the results of BackendTester.exe:

Starting run no 0
Generating file 0 (8.50 KB)
Generating file 1 (9.28 KB)
Uploading wrong files ...
Generating file 2 (1.98 KB)
Uploading file 0, 1.98 KB ...  done!
Uploading file 0, 1.98 KB ...  done!
Uploading file 1, 1.98 KB ...  done!
Uploading files ...
Uploading file 0, 8.50 KB ...  done!
Uploading file 1, 9.28 KB ...  done!
Verifying file list ...
Downloading files
Downloading file 0 ... done
Checking hash ... done
Downloading file 1 ... done
Checking hash ... done
Deleting files...
Checking retrieval of non-existent file...
Caught expected FileMissingException
Checking DNS names used by this backend...
api.backblazeb2.com
api002.backblazeb2.com
f002.backblazeb2.com
Unittest complete!

It looks like you used extra options, asking for small files. Small files work. Maybe do a run with defaults.

EDIT here’s why I say small files work. Look at size and hash line to see only a dblock exhaust 5 retries:

Each retry uses a new name, which is why yu have to look at size and hash data to see that it’s a retry.

Here’s the output of the last run with the default options. The previous runs looked similar:

Starting run no 4
Generating file 0 (3.24 MB)
Generating file 1 (28.96 MB)
Generating file 2 (32.75 MB)
Generating file 3 (27.48 MB)
Generating file 4 (11.12 MB)
Generating file 5 (19.84 MB)
Generating file 6 (24.04 MB)
Generating file 7 (36.35 MB)
Generating file 8 (331.18 KB)
Generating file 9 (32.37 MB)
Uploading wrong files ...
Generating file 10 (1.31 KB)
Uploading file 0, 1.31 KB ...  done!
Uploading file 0, 1.31 KB ...  done!
Uploading file 9, 1.31 KB ...  done!
Uploading files ...
Uploading file 0, 3.24 MB ...  done!
Uploading file 1, 28.96 MB ...  done!
Uploading file 2, 32.75 MB ...  done!
Uploading file 3, 27.48 MB ...  done!
Uploading file 4, 11.12 MB ...  done!
Uploading file 5, 19.84 MB ...  done!
Uploading file 6, 24.04 MB ...  done!
Uploading file 7, 36.35 MB ...  done!
Uploading file 8, 331.18 KB ...  done!
Uploading file 9, 32.37 MB ...  done!
Verifying file list ...
Downloading files
Downloading file 0 ... done
Checking hash ... done
Downloading file 1 ... done
Checking hash ... done
Downloading file 2 ... done
Checking hash ... done
Downloading file 3 ... done
Checking hash ... done
Downloading file 4 ... done
Checking hash ... done
Downloading file 5 ... done
Checking hash ... done
Downloading file 6 ... done
Checking hash ... done
Downloading file 7 ... done
Checking hash ... done
Downloading file 8 ... done
Checking hash ... done
Downloading file 9 ... done
Checking hash ... done
Deleting files...
Checking retrieval of non-existent file...
Caught expected FileMissingException
Checking DNS names used by this backend...
api.backblazeb2.com
api002.backblazeb2.com
f002.backblazeb2.com
Unittest complete!

I wonder if whatever the network + destination problem was has gone away now? That’d be nice.

I cut down the SQL query, but it’s still large, and I’d probably need a pre-break DB to compare to.
Because I’m not an SQL expert, and most SQL experts aren’t Duplicati experts, this is a hard job.

Anyone want to work on understanding the below cut-down query which is still returning 261396?
If a pre-break backup of the DB returns 261397, then one of the tables in this must have changed.

SELECT COUNT(*) FROM (SELECT DISTINCT "Path" FROM (
SELECT
    "L"."Path"
FROM
    (
    SELECT 
        "J"."Path", 
        "J"."MetablocksetID"
    FROM 
        (
        SELECT 
	        "A"."Path" AS "Path", 
	        "A"."BlocksetID" AS "BlocksetID",
	        "C"."BlocksetID" AS "MetablocksetID"
        FROM 
	        "FixedFile" A	
        LEFT JOIN "Blockset" B
          ON "A"."BlocksetID" = "B"."ID" 
        LEFT JOIN "Metadataset" C  
          ON "A"."MetadataID" = "C"."ID"
        LEFT JOIN "FilesetEntry" D
          ON "A"."ID" = "D"."FileID"
        LEFT JOIN "Blockset" E
          ON "E"."ID" = "C"."BlocksetID"
        LEFT JOIN "BlocksetEntry" G
          ON "B"."ID" = "G"."BlocksetID"
        LEFT JOIN "Block" F 
          ON "G"."BlockID" = "F"."ID"  
        LEFT JOIN "BlocksetEntry" I
          ON "E"."ID" = "I"."BlocksetID"
        LEFT JOIN "Block" H 
          ON "I"."BlockID" = "H"."ID"
        WHERE 
          "A"."BlocksetId" >= 0 AND
          "D"."FilesetID" = 1415 AND
          ("I"."Index" = 0 OR "I"."Index" IS NULL) AND  
          ("G"."Index" = 0 OR "G"."Index" IS NULL)
        ) J
    LEFT OUTER JOIN 
        "BlocklistHash" K 
    ON 
        "K"."BlocksetID" = "J"."BlocksetID" 
    ORDER BY "J"."Path", "K"."Index"
    ) L

LEFT OUTER JOIN
    "BlocklistHash" M
ON
    "M"."BlocksetID" = "L"."MetablocksetID"
) UNION SELECT DISTINCT "Path" FROM (
SELECT
    "G"."BlocksetID",
    "G"."Path"
FROM
    (
    SELECT
        "B"."BlocksetID",
        "B"."ID",
        "B"."Path",
        "C"."BlocksetID" AS "MetaBlocksetID"
    FROM
        "FilesetEntry" A, 
        "FixedFile" B, 
        "Metadataset" C, 
        "Blockset" D,
        "BlocksetEntry" E,
        "Block" F
    WHERE 
        "A"."FileID" = "B"."ID" 
        AND "B"."MetadataID" = "C"."ID" 
        AND "C"."BlocksetID" = "D"."ID" 
        AND "E"."BlocksetID" = "C"."BlocksetID"
        AND "E"."BlockID" = "F"."ID"
        AND "E"."Index" = 0
        AND ("B"."BlocksetID" = -100 OR "B"."BlocksetID" = -200) 
        AND "A"."FilesetID" = 1415
    ) G
LEFT OUTER JOIN
   "BlocklistHash" H
ON
   "H"."BlocksetID" = "G"."MetaBlocksetID"
ORDER BY
   "G"."Path", "H"."Index"

))

Because I’m not convinced that a volunteer will immediately solve the above, maybe it’s time to delete versions and see what happens. The problem might move to the next newer version, meaning version number reported goes down (newest is 0) but internal FilesetID goes up. Eventually the end will be hit.

EDIT:

Or you can start a fresh backup while exploring, or you can get an old database and at least test query.
Figuring out which table changed is harder, but it would be interesting to see old database say 261397.

I mean, that’s what I think given that my database backup worked fine this morning. The main backup didn’t work, but that’s because of the Unexpected difference in fileset error now, not the original The socket has been shut down error.

I don’t know if I’d say I’m a SQL expert, but I’m no slouch either. What exactly is the question you need answered?

First question is whether a database before things broke (seemingly yesterday, but may need fishing) returns 261397? On which version of database did it go to 261396, which is causing verify complaint?

A lot of these tables are changing all the time, at the very least being updated with latest backup data. The key would be to understand the query well enough (or cut it into subqueries) to see how database giving 261396 differs from database giving 261397. At that point we might still not fully understand the cause, because there is no profiling log, which logs most of the queries. But some light might be shed.

There’s a little bit of information on tables and relationships, if you really want to try to get in very deep.

Ultimately the question is what happened to cause this. We lack good logs, but we have old databases which is rather unusual. Typically there’s nothing, which makes it very hard to look into this sort of thing.

Before I dig into that aspect… forgive me if this is a stupid question, but is it possible that a file delete was called and the file was deleted from the remote store, but something interrupted the process before that delete could be reflected in the database? Could that account for one fewer file being found while the database expects one more?

There is a very loose relationship between destination files and source files, so it seems rather unlikely.

How the backup process works

Although it’s far from a 1-to-1 relationship, it’s quite possible that some transfer error helped lead to this.

EDIT: For example a dblock upload that fails has to back out DB awareness that those blocks uploaded.
Maybe inadvertently backing out a little too much led to the count computed by all that SQL going down.

EDIT 2: Another avenue of attack would be to not just go by its count, but actually look at Path changes.
If it’s seen which file that should be available went unavailable, that’s something concrete to investigate.

Can you provide a query that returns all of the files in fileset 1415? From there, I can whip up a MINUS query to see what file shakes out at the end.

Here is the code:

var storedlist = cmd2.ExecuteScalarInt64(@“SELECT COUNT(*) FROM ““FilesetEntry”” WHERE ““FilesetEntry””.”“FilesetID”" = ?", 0, filesetid);

the result is compared to the very complicated query quoted by @ts678

One note is that if you see “FixedFile”, that’s what the bug report made from the original “File” view.
Actual paths are removed for privacy, but you can cite the other row information for the errant Path.

I put together a quick query to see what the difference is, but I’m getting unexpected results.

My query is:

SELECT 		f.Path
FROM 		"FilesetEntry" fe
left JOIN	"File" f
on			fe.FileID = f.ID
WHERE 		fe."FilesetID" = "1415"

EXCEPT

SELECT DISTINCT "Path"
          FROM (SELECT "L"."Path"
                  FROM (SELECT "J"."Path", "J"."MetablocksetID"
                          FROM (SELECT "A"."Path"       AS "Path",
                                       "A"."BlocksetID" AS "BlocksetID",
                                       "C"."BlocksetID" AS "MetablocksetID"
                                  FROM "File" A
                                  LEFT JOIN "Blockset" B
                                    ON "A"."BlocksetID" = "B"."ID"
                                  LEFT JOIN "Metadataset" C
                                    ON "A"."MetadataID" = "C"."ID"
                                  LEFT JOIN "FilesetEntry" D
                                    ON "A"."ID" = "D"."FileID"
                                  LEFT JOIN "Blockset" E
                                    ON "E"."ID" = "C"."BlocksetID"
                                  LEFT JOIN "BlocksetEntry" G
                                    ON "B"."ID" = "G"."BlocksetID"
                                  LEFT JOIN "Block" F
                                    ON "G"."BlockID" = "F"."ID"
                                  LEFT JOIN "BlocksetEntry" I
                                    ON "E"."ID" = "I"."BlocksetID"
                                  LEFT JOIN "Block" H
                                    ON "I"."BlockID" = "H"."ID"
                                 WHERE "A"."BlocksetId" >= 0
                                   AND "D"."FilesetID" = 1415
                                   AND ("I"."Index" = 0 OR "I"."Index" IS NULL)
                                   AND ("G"."Index" = 0 OR "G"."Index" IS NULL)) J
                          LEFT OUTER JOIN "BlocklistHash" K
                            ON "K"."BlocksetID" = "J"."BlocksetID"
                         --ORDER BY "J"."Path", "K"."Index"
						 ) L
                
                  LEFT OUTER JOIN "BlocklistHash" M
                    ON "M"."BlocksetID" = "L"."MetablocksetID")
        
        UNION
        
        SELECT DISTINCT "Path"
          FROM (SELECT "G"."BlocksetID", "G"."Path"
                  FROM (SELECT "B"."BlocksetID",
                               "B"."ID",
                               "B"."Path",
                               "C"."BlocksetID" AS "MetaBlocksetID"
                          FROM "FilesetEntry"  A,
                               "File"     B,
                               "Metadataset"   C,
                               "Blockset"      D,
                               "BlocksetEntry" E,
                               "Block"         F
                         WHERE "A"."FileID" = "B"."ID"
                           AND "B"."MetadataID" = "C"."ID"
                           AND "C"."BlocksetID" = "D"."ID"
                           AND "E"."BlocksetID" = "C"."BlocksetID"
                           AND "E"."BlockID" = "F"."ID"
                           AND "E"."Index" = 0
                           AND ("B"."BlocksetID" = -100 OR
                               "B"."BlocksetID" = -200)
                           AND "A"."FilesetID" = 1415) G
                  LEFT OUTER JOIN "BlocklistHash" H
                    ON "H"."BlocksetID" = "G"."MetaBlocksetID"
                 --ORDER BY "G"."Path", "H"."Index"
                
                )

Since the counts on each each of the two sides of the EXCEPT is 261,397 and 261,396, respectively, I would expect the EXCEPT query to return 1 row. However, it’s returning 66,406 rows. That tells me that the paths in each side of the query are different for some reason?

I’m not sure what to make of that, but hopefully somebody can point out what I’m doing wrong. From what I can tell, all of the 66,406 results of the EXCEPT query are directories, not files.

Any ideas?

EDIT: I ran this query to count the number of directories, and I get 66,399.

SELECT 		count(*) --f.PATH
FROM 		"FilesetEntry" fe
left JOIN	"File" f
on			fe.FileID = f.ID
WHERE 		fe."FilesetID" = '1415'
AND f.PATH like '%/'

This means the results of the EXCEPT query are suspiciously close to being just every directory in the fileset.

@tkohhh

I think that what you are seeing is more a bug/limitation in sqlite than in Duplicati.
Just save the 2 different queries by adding ‘create table…’ before and run the except on the 2 generated tables.

Line 802 in source above shows the query is filesets UNION folders and symlinks.
I can’t quickly find a statement on precedence, but maybe it runs left to right, thus:

(expected filesets folders and symlinks EXCEPT filesets) UNION folders and symlinks

thus

I tried using parentheses to set order, but got a syntax error. I’m sure there’s a way.

EDIT:

I tried adding a SELECT * FROM before my previous parenthesis addition. Result:

image

EDIT 2:

Fiddling with the query, first by ORDER BY “Path” then faster AND “Path” IS NULL:

image

FilesetEntry table thinks it has a FileID 3838716:

image

FixedFile table doesn’t. I wonder how old DB is?

image

Local database describes some of the relationships.
Database rebuild and neighbor posts add some text.

Yeah, this is correct. I thought the union was already wrapped in a select… my bad!

After wrapping it in a select, I’m getting the same Null result. So, I updated the queries to pull FileID rather than Path, and sure enough I get FileID 3838716 as the result.

In case it’s helpful in the future, here’s the EXCEPT query that works:

SELECT 		fe.FileID
FROM 		"FilesetEntry" fe
left JOIN	"File" f
on			fe.FileID = f.ID
WHERE 		fe."FilesetID" = 1415

EXCEPT

select ID from (
SELECT DISTINCT "ID"
          FROM (SELECT "L"."Path", L.ID
                  FROM (SELECT "J"."Path", "J"."MetablocksetID", J.ID
                          FROM (SELECT "A"."Path"       AS "Path",
                                       "A"."BlocksetID" AS "BlocksetID",
                                       "C"."BlocksetID" AS "MetablocksetID"
									   ,A.ID
                                  FROM "File" A
                                  LEFT JOIN "Blockset" B
                                    ON "A"."BlocksetID" = "B"."ID"
                                  LEFT JOIN "Metadataset" C
                                    ON "A"."MetadataID" = "C"."ID"
                                  LEFT JOIN "FilesetEntry" D
                                    ON "A"."ID" = "D"."FileID"
                                  LEFT JOIN "Blockset" E
                                    ON "E"."ID" = "C"."BlocksetID"
                                  LEFT JOIN "BlocksetEntry" G
                                    ON "B"."ID" = "G"."BlocksetID"
                                  LEFT JOIN "Block" F
                                    ON "G"."BlockID" = "F"."ID"
                                  LEFT JOIN "BlocksetEntry" I
                                    ON "E"."ID" = "I"."BlocksetID"
                                  LEFT JOIN "Block" H
                                    ON "I"."BlockID" = "H"."ID"
                                 WHERE "A"."BlocksetId" >= 0
                                   AND "D"."FilesetID" = 1415
                                   AND ("I"."Index" = 0 OR "I"."Index" IS NULL)
                                   AND ("G"."Index" = 0 OR "G"."Index" IS NULL)) J
                          LEFT OUTER JOIN "BlocklistHash" K
                            ON "K"."BlocksetID" = "J"."BlocksetID"
                         --ORDER BY "J"."Path", "K"."Index"
						 ) L
                
                  LEFT OUTER JOIN "BlocklistHash" M
                    ON "M"."BlocksetID" = "L"."MetablocksetID")
        
        UNION
        
        SELECT DISTINCT "ID"
          FROM (SELECT "G"."BlocksetID", "G"."Path", G.ID
                  FROM (SELECT "B"."BlocksetID",
                               "B"."ID",
                               "B"."Path",
                               "C"."BlocksetID" AS "MetaBlocksetID"
                          FROM "FilesetEntry"  A,
                               "File"     B,
                               "Metadataset"   C,
                               "Blockset"      D,
                               "BlocksetEntry" E,
                               "Block"         F
                         WHERE "A"."FileID" = "B"."ID"
                           AND "B"."MetadataID" = "C"."ID"
                           AND "C"."BlocksetID" = "D"."ID"
                           AND "E"."BlocksetID" = "C"."BlocksetID"
                           AND "E"."BlockID" = "F"."ID"
                           AND "E"."Index" = 0
                           AND ("B"."BlocksetID" = -100 OR
                               "B"."BlocksetID" = -200)
                           AND "A"."FilesetID" = 1415) G
                  LEFT OUTER JOIN "BlocklistHash" H
                    ON "H"."BlocksetID" = "G"."MetaBlocksetID"
                 --ORDER BY "G"."Path", "H"."Index"
                
                )
)

For my queries, I copied the sqlite database yesterday, so it’s current. Or is there something else you mean by this?

For now, I’m going to pull up an old copy of the database and see what File 3838716 is. edit: the missing file is a measly log file from my Nextcloud server.

As for fixing the problem, do you have any suggestions?