@@ -17,7 +17,7 @@ private static async Task<int> Main()
17
17
Log . Logger = new LoggerConfiguration ( )
18
18
. MinimumLevel . Debug ( )
19
19
. WriteTo . Console ( )
20
- . WriteTo . File ( "mongo.txt" )
20
+ // .WriteTo.File("mongo.txt")
21
21
. CreateLogger ( ) ;
22
22
23
23
var envMongoConnectionString = Environment . GetEnvironmentVariable ( "MongoConnectionString" ) ;
@@ -50,8 +50,10 @@ private static async Task<int> Main()
50
50
Log . Information ( "Starting.. IsDryRun: {0}. Connection information: {@1}" , isDryRun , mongoSettings ) ;
51
51
52
52
var sw = new Stopwatch ( ) ;
53
+ var filesDeleted = 0 ;
54
+ var orphanedChunks = 0UL ;
53
55
var validFiles = new HashSet < ObjectId > ( ) ;
54
- var deletedFiles = new HashSet < ObjectId > ( ) ;
56
+ var filesToDelete = new HashSet < ObjectId > ( ) ;
55
57
56
58
// The projection and hint let us do this whole thing as a covered query
57
59
// https://docs.mongodb.com/manual/core/query-optimization/#covered-query
@@ -61,9 +63,6 @@ private static async Task<int> Main()
61
63
Hint = "files_id_1_n_1"
62
64
} ;
63
65
64
- // Just to see that the program is working as this can take a while.
65
- var timer = new Timer ( ( s ) => Log . Information ( "Valid files count: {0}" , validFiles . Count ) , null , 0 , 10_000 ) ;
66
-
67
66
try
68
67
{
69
68
Log . Information ( "Creating cursor and starting search of orphaned chunks.." ) ;
@@ -72,12 +71,14 @@ private static async Task<int> Main()
72
71
using var chunksCursor = await chunks . FindAsync ( Builders < BsonDocument > . Filter . Empty , findOptions ) ;
73
72
while ( await chunksCursor . MoveNextAsync ( ) )
74
73
{
74
+ orphanedChunks += ( ulong ) chunksCursor . Current . Count ( ) ;
75
75
var uniqueFileIds = chunksCursor . Current . Select ( x => x [ "files_id" ] . AsObjectId ) . ToHashSet ( ) ;
76
+
76
77
foreach ( var fileId in uniqueFileIds )
77
78
{
78
79
// Don't check it if we already know it's valid
79
80
// Don't check if we already deleted
80
- if ( validFiles . Contains ( fileId ) || deletedFiles . Contains ( fileId ) )
81
+ if ( validFiles . Contains ( fileId ) || filesToDelete . Contains ( fileId ) )
81
82
{
82
83
continue ;
83
84
}
@@ -90,33 +91,42 @@ private static async Task<int> Main()
90
91
continue ;
91
92
}
92
93
93
- var deleteResult = 0L ;
94
- // If we know it isn't valid, delete all possible chunks with a single command
95
- if ( isDryRun )
96
- {
97
- deleteResult = await chunks . CountDocumentsAsync ( Builders < BsonDocument > . Filter . Eq ( "files_id" , fileId ) ) ;
98
- Log . Information ( "Dry-run: Could delete {0} chunks from orphaned file {@1}" , deleteResult , new { Id = fileId . ToString ( ) , fileId . CreationTime } ) ;
99
- }
100
- else
101
- {
102
- var deleteResults = await chunks . DeleteManyAsync ( Builders < BsonDocument > . Filter . Eq ( "files_id" , fileId ) ) ;
103
- deleteResult = deleteResults . DeletedCount ;
104
- Log . Information ( "Deleted {0} chunks from orphaned file {@1}" , deleteResult , new { Id = fileId . ToString ( ) , fileId . CreationTime } ) ;
105
- }
94
+ filesToDelete . Add ( fileId ) ;
95
+ }
96
+ }
97
+
98
+ Log . Information ( "Found '{0}' files and {1} orphaned chunks." , filesToDelete . Count , orphanedChunks ) ;
99
+ Log . Information ( "Elapsed time: {0}" , sw . Elapsed . ToString ( ) ) ;
100
+ Log . Information ( "Starting deletion process.." ) ;
106
101
107
- deletedFiles . Add ( fileId ) ;
102
+ // Do this outside the cursor loop to avoid cursor timeout
103
+ foreach ( var files_id in filesToDelete )
104
+ {
105
+ if ( isDryRun )
106
+ {
107
+ var deleteResult = await chunks . CountDocumentsAsync ( Builders < BsonDocument > . Filter . Eq ( "files_id" , files_id ) ) ;
108
+ Log . Information ( "Dry-run: Could delete {0} chunks from orphaned file {@1}" , deleteResult , new { Id = files_id . ToString ( ) , files_id . CreationTime } ) ;
109
+ filesDeleted ++ ;
110
+ }
111
+ else
112
+ {
113
+ // If we know it isn't valid, delete all possible chunks with a single command
114
+ var deleteResult = await chunks . DeleteManyAsync ( Builders < BsonDocument > . Filter . Eq ( "files_id" , files_id ) ) ;
115
+ Log . Information ( "Deleted {0} chunks from orphaned file {@1}" , deleteResult . DeletedCount , new { Id = files_id . ToString ( ) , files_id . CreationTime } ) ;
116
+ filesDeleted ++ ;
108
117
}
109
118
}
110
119
}
111
120
catch ( Exception ex )
112
121
{
113
- Log . Error ( ex , "Something went wrong." ) ;
122
+ Log . Error ( ex , "Deletion process stopped. Something went wrong." ) ;
114
123
}
115
124
finally
116
125
{
117
126
sw . Stop ( ) ;
118
- Log . Information ( "Elapsed time: {0} minutes." , sw . Elapsed . TotalMinutes ) ;
119
- Log . Information ( "Deleted '{0}' files: {1}" , deletedFiles . Count , string . Join ( "," , deletedFiles . Select ( x => x . ToString ( ) ) ) ) ;
127
+ Log . Information ( "Deletion process finished." ) ;
128
+ Log . Information ( "Elapsed time: {0}." , sw . Elapsed . ToString ( ) ) ;
129
+ Log . Information ( "Deleted '{0}' files" , filesDeleted ) ;
120
130
Log . CloseAndFlush ( ) ;
121
131
}
122
132
0 commit comments