Commit 4f26228
committed
[SPARK-58985][CORE] Fix HistoryServerDiskManager double-counting store size on concurrent release and makeRoom
### What changes were proposed in this pull request?
Make the disk usage accounting in `HistoryServerDiskManager` atomic with the store operation it accompanies:
- `release()` now performs the whole operation -- removing the app from the `active` map, updating usage accounting, and deleting or re-measuring the store -- under the `active` lock. When the store directory is already gone, it also drops the listing entry so the store is not deducted again later.
- `Lease.commit()` now moves the store into place, updates usage accounting, writes the listing entry, and registers the app in the `active` map under the `active` lock, so the store is never on disk without being tracked. A failed rename raises an `IOException` instead of recording a store that is not there. When the previous store directory is already gone but still listed, its listing entry and accounting are dropped before the new store takes its place.
- `openStore()` now writes the listing entry under the `active` lock, so a concurrent `release()` cannot leave a listing entry for a deleted store.
- `makeRoom()` re-checks each eviction candidate under the `active` lock before deleting it: it skips candidates that became active or that a concurrent `release()` or `commit()` already deleted, and deducts the size the listing holds at that point. The summary log reports the stores actually deleted and the space actually freed, and warns when nothing could be freed. On that log line, `NUM_BYTES_EVICTED` now carries the freed bytes and `NUM_BYTES_TO_FREE` the target, and the store count moves to `NUM_APPS`; consumers of these structured-logging fields should note the change.
The lock now covers directory I/O (`sizeOf`, rename, deletion, listing read/write). As a trade-off, `openStore()` from UI requests can block while a concurrent `release()` (e.g., in the `cleanLogs` loop) or `makeRoom()` eviction deletes a store; this is deliberate to keep the accounting accurate.
### Why are the changes needed?
`HistoryServerDiskManager` can deduct the same store size twice, driving the committed usage negative and making the History Server throw `IllegalStateException: Disk usage tracker went negative`.
The race is longstanding: `release()` updates usage and operates on the store directory outside the `active` lock, `commit()` moves the store into place before registering it, and `makeRoom()` deletes eviction candidates without re-checking, so two paths have been able to deduct the same store since the disk manager was introduced by SPARK-20654 (2.3.0).
SPARK-56044 (4.0.3) widened the race. By adding a deduction in `release()` based on the size measured from disk for apps not in the `active` map, a double deduction no longer requires the application to be actively open:
- `release(delete = true)` vs `openStore()`: `release()` deducts the measured size and deletes the store, but a concurrent `openStore()` re-registered the app in `active`, so a subsequent `release()` deducts the size again.
- `release(delete = true)` vs `commit()`: `commit()` has moved the store into place but not yet registered it, so `release()` deducts the measured size and deletes the store; `commit()` then registers the deleted store, and a subsequent `release()` deducts the size again.
- `release(delete = true)` vs `makeRoom()`: both paths deduct the size of the same store.
This makes the race reachable in normal History Server operation, e.g. log cleanup calling `release(delete = true)` for an app never opened after a restart while a concurrent UI request opens, loads, or evicts the same store. The fix also closes two concurrent `makeRoom()` calls evicting the same store twice.
This crash was observed on a production History Server (4.1-based build), in the periodic log cleanup path:
```
java.lang.IllegalStateException: Disk usage tracker went negative (now = -118595158, delta = -151974353)
at o.a.s.deploy.history.HistoryServerDiskManager.updateUsage(HistoryServerDiskManager.scala:285)
at o.a.s.deploy.history.HistoryServerDiskManager.release(HistoryServerDiskManager.scala:186)
at o.a.s.deploy.history.FsHistoryProvider.cleanAppData(FsHistoryProvider.scala:746)
at o.a.s.deploy.history.FsHistoryProvider.deleteAttemptLogs(FsHistoryProvider.scala:1132)
at o.a.s.deploy.history.FsHistoryProvider.cleanLogs(FsHistoryProvider.scala:1063)
at o.a.s.deploy.history.FsHistoryProvider.$anonfun$startPolling$4(FsHistoryProvider.scala:305)
```
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Added five tests to `HistoryServerDiskManagerSuite`. The three race tests (`release with delete is atomic with openStore`, `makeRoom is atomic with release`, `commit is atomic with release`) park one operation mid-way, run the competing operation on another thread, and let the parked one proceed once the competing thread has finished or blocked on the lock, so none relies on a fixed wait. Each fails on the pre-fix code, the first with `openStore()` handing out a store being deleted, the other two with `IllegalStateException: Disk usage tracker went negative`. `makeRoom deducts a store deleted out of band` and `commit deducts a store deleted out of band` pin the accounting for stores removed outside the History Server.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Qwen 3.8 Max
Closes #58312 from pan3793/SPARK-58985.
Authored-by: Cheng Pan <pan3793@gmail.com>
Signed-off-by: Cheng Pan <chengpan@apache.org>
(cherry picked from commit ff9d3e3)
Signed-off-by: Cheng Pan <chengpan@apache.org>1 parent 32f7e10 commit 4f26228
2 files changed
Lines changed: 255 additions & 59 deletions
File tree
- core/src
- main/scala/org/apache/spark/deploy/history
- test/scala/org/apache/spark/deploy/history
Lines changed: 92 additions & 55 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| |||
139 | 141 | | |
140 | 142 | | |
141 | 143 | | |
142 | | - | |
143 | | - | |
| 144 | + | |
144 | 145 | | |
145 | 146 | | |
146 | | - | |
| 147 | + | |
147 | 148 | | |
| 149 | + | |
148 | 150 | | |
149 | 151 | | |
150 | 152 | | |
151 | 153 | | |
152 | 154 | | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | 155 | | |
160 | 156 | | |
161 | 157 | | |
162 | 158 | | |
| 159 | + | |
| 160 | + | |
163 | 161 | | |
164 | 162 | | |
165 | 163 | | |
166 | 164 | | |
167 | 165 | | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
176 | 175 | | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
187 | 197 | | |
188 | | - | |
189 | 198 | | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
196 | 202 | | |
197 | 203 | | |
198 | 204 | | |
| |||
226 | 232 | | |
227 | 233 | | |
228 | 234 | | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
229 | 244 | | |
230 | 245 | | |
231 | 246 | | |
| |||
246 | 261 | | |
247 | 262 | | |
248 | 263 | | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
261 | 288 | | |
262 | 289 | | |
263 | 290 | | |
| |||
320 | 347 | | |
321 | 348 | | |
322 | 349 | | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
323 | 357 | | |
324 | 358 | | |
325 | 359 | | |
326 | 360 | | |
327 | 361 | | |
328 | 362 | | |
329 | 363 | | |
330 | | - | |
331 | 364 | | |
332 | | - | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
333 | 376 | | |
334 | 377 | | |
335 | 378 | | |
336 | 379 | | |
337 | 380 | | |
338 | 381 | | |
339 | 382 | | |
340 | | - | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | 383 | | |
347 | 384 | | |
348 | 385 | | |
| |||
0 commit comments