-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Swift 损坏、备份、修复
sanhuazhang edited this page Dec 20, 2017
·
5 revisions
数据库作为二进制文件,当内部有部分数据不一致或丢失时,可能会发生数据库损坏。数据不一致或丢失的原因较多,可能是代码问题、操作系统或文件系统故障、磁盘损坏等等。从根源上,数据库损坏是不可能完全避免的。
因此,WCDB Swift 内建了修复工具,可以尽最大限度地将数据找回,减少数据丢失。
在监控与错误处理一章,已经提到了监控和处理错误信息了。
损坏也可以用同样地方式监控,当错误类型为 SQLite
且错误码为 11 或 26 时,代表发生了数据库损坏,然后可以根据 tag
确认损坏的数据库,而后进行处理。
Database.globalTrace(ofError: { (error: WCDBSwift.Error) in
if error.type == .sqlite && (error.code.value == 11 || error.code.value == 26) {
print("Tag: \(error.tag) is corrupted")
}
})
在有备份的情况,修复工具的能力将大大提升。在数据库内的数据发生变化时,元数据备份有可能会过期。因此建议在子线程定期对其备份。
DispatchQueue.global(qos: .background).async {
Timer.scheduledTimer(withTimeInterval: 5 * 60, repeats: true) {_ in
let backupPassword = "backupPassword".data(using: .ascii)
try? database.backup(withKey: backupPassword)
}
}
元数据通常只有几 kb 大小,且属于读操作,可以与其他操作并发执行。因此备份不会对性能产生大的影响。
数据库修复通过 recover(fromPath:withPageSize:databaseKey:backupKey:)
接口完成。它将尝试从已损坏的数据库中读出数据,并插入到新数据库中。其函数原型为:
func recover(fromPath source: String, // 已损坏的数据库路径
withPageSize pageSize: Int32 = 4096, // 已损坏的数据库的page size
databaseKey: Data? = nil, // 已损坏的数据库的密码,若未加密,则为 nil
backupKey: Data? = nil) throws // 元数据备份的密码,若备份未加密,则为 nil
修复过程根据数据库的大小不同,需要一定的时间。建议在界面上提示等待,并在子线程进行修复。
//view.startLoading()
DispatchQueue.global(qos: .background).async {
let newDatabase = Database(withPath: "newPath")
try? newDatabase.recover(fromPath: pathToCorruptedDatabase,
withPageSize: 4096,
databaseKey: corruptedDatabaseKey,
backupKey: backupKey)
//DispatchQueue.main.async {
// view.stopLoading()
//}
}
对于可再生的数据,如可从服务端重新拉取的数据,直接将数据库删掉重建是更好的恢复手段。
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程