fix: resolve resource leaks in stream handling and VACUUM INTO - #65
Merged
Merged
Conversation
- Fix ZipInputStream returned closed: change .use{} to .also{} in
getInputStreamInternal so compress-type-2 entries return an open stream
instead of a closed one that causes IOException on read.
- Fix exception-unsafe close in packFiles and zipArchive: replace
input.copyTo(); input.close() with input.use{} to guarantee cleanup
even when copyTo throws (e.g., disk full).
- Fix VACUUM INTO connection leak in scheduled backup: close the Exposed
DatabaseConnection via try/finally and the JDBC Statement via .use{},
preventing connection leaks on every scheduled backup cycle.
Owner
|
这些修复基本上没问题,但是是否真正解决了内存泄露,还需要你帮忙确认测试。谢谢你! |
Contributor
Author
|
在提PR之前我已经安装在服务器上并测试过了,没有出现之前的泄漏问题😉 感谢合并! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
English
Summary
This PR fixes several resource leak bugs in the backup system that cause file descriptor exhaustion and database connection leaks on long-running servers. Closes #64
This PR uses AI.
Changes
1. Fix ZipInputStream returned closed (compress type 2)
BackupDatabaseService.kt:156The old code
ZipInputStream(...).use { ... it }returned a closed stream because Kotlin's.use {}closes the resource before returning the block result. All callers (packFiles, zipArchive) would receive a closed stream and throwIOException: Stream closedwhen trying to read compress-type-2 entries.Fix: Changed
.useto.also, which returns the open stream after executing the block.2. Fix exception-unsafe stream close in packFiles and zipArchive
BackupDatabaseService.kt:601, 654The old pattern
input.copyTo(target); input.close()is not exception-safe. IfcopyTo()throws (disk full, broken pipe),close()never executes, leaking the underlyingFileInputStream.Fix: Replaced with
input.use { s -> s.copyTo(target) }, which guarantees cleanup even on exception.3. Fix VACUUM INTO connection leak in scheduled backup
XBackup.kt:310The old code created a new Exposed
DatabaseConnectionand JDBCStatementbut never closed either. This code runs inside the crontab loop (every ~10 seconds when a backup is due), so each scheduled backup leaked one connection + Statement. Over time this causes "database is locked" errors.Fix: Added
try/finally { exposedConn.close() }for the connection and.use {}for the statement.Testing
Tested in-game: manual/automatic backup, restore, and all CLI commands work correctly. Server runs stable for over 11 days without crashes after installing this fix.
中文
概述
本PR修复了备份系统中的多个资源泄漏问题,这些问题会导致长时间运行的服务器出现文件描述符耗尽和数据库连接泄漏。关闭issue #64
此PR使用AI编写。
修改内容
1. 修复 ZipInputStream 返回已关闭流的问题(压缩类型2)
BackupDatabaseService.kt:156旧代码
ZipInputStream(...).use { ... it }返回了一个已关闭的流,因为 Kotlin 的.use {}会在返回块结果之前关闭资源。所有调用者(packFiles、zipArchive)在读取压缩类型2的条目时都会收到一个已关闭的流,并抛出IOException: Stream closed。修复: 将
.use改为.also,后者在执行块后返回打开的流。2. 修复 packFiles 和 zipArchive 中不安全的流关闭方式
BackupDatabaseService.kt:601, 654旧模式
input.copyTo(target); input.close()不具备异常安全性。如果copyTo()抛出异常(磁盘满、管道断裂),close()永远不会执行,导致底层FileInputStream泄漏。修复: 替换为
input.use { s -> s.copyTo(target) },确保即使在异常情况下也能正确清理资源。3. 修复定时备份中 VACUUM INTO 的连接泄漏
XBackup.kt:310旧代码创建了新的 Exposed
DatabaseConnection和 JDBCStatement,但从未关闭它们。这段代码在定时任务循环中运行(备份就绪时每~10秒一次),因此每次定时备份都会泄漏一个连接和Statement。长时间运行后会导致 "database is locked" 错误。修复: 使用
try/finally { exposedConn.close() }关闭连接,使用.use {}关闭Statement。测试
已在游戏内测试:手动/自动备份、恢复(restore)功能正常,其他命令行功能正常。安装后服务器可正常运行超过11天不崩溃。