SQLite使用的临时文件(二)

返回:SQLite—系列文章目录   

上一篇:SQLite数据库文件损坏的可能几种情况

下一篇:SQLite数据库成为内存中数据库(三)

​ 1. 引言

SQLite的显着特点之一它是一个数据库由一个磁盘文件组成。 这简化了 SQLite 的使用,因为移动或备份 数据库就像复制单个文件一样简单。它还使 SQLite适合用作应用程序文件格式。 但是,当一个完整的数据库保存在单个磁盘文件中时, SQLite确实在处理数据库的过程。

本文介绍SQLite的各种临时文件创建和使用。它描述了何时创建文件,何时它们被删除,它们的用途,为什么它们很重要, 以及如何在创建临时文件的系统上避免它们陷阱。

不考虑SQLite使用临时文件的方式 SQLite与应用程序签订的合约的一部分。这 本文档中的信息是对如何操作的正确描述 SQLite在编写本文档时或最后编写时运行更新。但是不能保证SQLite的未来版本 将以相同的方式使用临时文件。新型临时可能会使用文件,并且一些当前的临时文件使用可能会停止在SQLite 的未来版本中。

2. 九种临时文件

SQLite目前使用九种不同类型的临时文件:

  1. 回滚日志
  2. 超级期刊
  3. 预写日志 (WAL) 文件
  4. 共享内存文件
  5. 报表日记帐
  6. TEMP 数据库
  7. 视图和子查询的具体化
  8. 瞬态指数
  9. VACUUM 使用的瞬态数据库

有关每个这些临时文件类型的附加信息 在续集中。

2.1. 回滚日志

回滚日志是用于实现的临时文件 SQLite中的原子提交和回滚功能。(有关其工作原理的详细讨论,请参阅 标题为 Atomic Commit In SQLite 的单独文档。 回滚日志始终位于同一目录中作为数据库文件,并且与数据库同名文件,但附加了 8 个字符的“-journal”除外。 回滚日志通常在事务发生时创建首先启动,通常在事务时被删除 提交或回滚。 回滚日志文件对于实现 SQLite的原子提交和回滚功能。没有 回滚日志,SQLite 将无法回滚 事务不完整,以及是否发生崩溃或断电在事务过程中,整个数据库可能会在没有回滚日志的情况下损坏。

回滚日志通常在事务的开始和结束。但也有例外到这个规则。

如果在交易过程中发生崩溃或断电, 然后,回滚日志文件将保留在磁盘上。下次 另一个应用程序尝试打开数据库文件,它注意到 被遗弃的回滚日志的存在(我们称之为“热 journal“,并使用 日志将数据库还原到启动前的状态 未完成的交易。这就是SQLite的实现方式 原子提交。

如果应用程序使用 选项:

PRAGMA locking_mode=EXCLUSIVE;

SQLite 在第一个 独占锁定模式会话中的事务。但是在 事务结束时,它不会删除回滚 杂志。回滚日志可能被截断,或者其标头可能被截断 可能归零(取决于您使用的 SQLite 版本) 但不会删除回滚日志。回滚日志是 在退出独占访问模式之前不会删除。

回滚日志的创建和删除也会被journal_mode编译指示更改。 默认日记模式为 DELETE,这是默认行为 在每个事务结束时删除回滚日志文件, 如上所述。PERSIST 日志模式放弃删除 日志文件,而是覆盖回滚日志头 使用零,以防止其他进程回滚 日志,因此具有与删除日志文件相同的效果 无需实际从磁盘中删除文件的费用。在其他 words,日志模式 PERSIST 表现出与所见相同的行为 在 EXCLUSIVE 锁定模式下。这 OFF 日志模式会导致 SQLite 完全省略回滚日志。 换言之,如果日志模式为 设置为 OFF。 OFF 日志模式禁用原子 SQLite的提交和回滚功能。ROLLBACK 命令 设置了 OFF 日志模式时不可用。如果发生碰撞或电源 损失发生在使用 OFF 日志的事务中间 模式下,无法恢复,数据库文件可能会 去腐败。 MEMORY 日志模式导致回滚日志存储在内存而不是磁盘。ROLLBACK 命令在以下情况下仍然有效日志模式是 MEMORY,但因为磁盘上不存在 恢复、崩溃或断电 在使用 MEMORY 日志模式可能会导致数据库损坏。

2.2. 预写日志(WAL)文件

使用预写日志或 WAL 文件代替回滚日志 当 SQLite 在 WAL 模式下运行时。与回滚日志一样, WAL 文件的目的是实现原子提交和回滚。 WAL 文件始终位于同一目录中 作为数据库文件,并且与数据库同名 文件,但附加了 4 个字符“-wal”的文件除外。 WAL 文件是在首次连接到 数据库被打开,通常在最后 与数据库的连接将关闭。但是,如果最后一个连接 没有干净地

### 删除 SQLite 临时文件的方法 SQLite 在运行过程中可能会生成一些临时文件来支持事务、排序或其他内部操作。这些临时文件通常会在正常情况下由 SQLite 自动清理,但如果某些异常情况发生(如程序崩溃),可能需要手动干预。 #### 方法一:确保正常的关闭流程 SQLite 的设计使得大多数临时文件在其连接关闭时会被自动删除[^3]。因此,最简单的办法是确保所有的数据库连接都已正确关闭。可以通过调用 `sqlite3_close()` 函数来释放资源并触发临时文件的清理过程。 ```c int rc = sqlite3_close(db); if (rc != SQLITE_OK) { fprintf(stderr, "Error closing database: %s\n", sqlite3_errmsg(db)); } ``` 如果所有连接都被成功关闭,则大部分临时文件应该已经被移除。 --- #### 方法:设置临时目录路径 通过配置环境变量或使用 API 设置临时文件的位置,可以更方便地管理它们。例如: - **Windows**: 修改 `%TEMP%` 或 `%TMP%` 环境变量。 - **Linux/Unix**: 修改 `$TMPDIR` 环境变量。 或者可以直接指定 SQLite 创建临时文件的具体位置,通过以下函数实现: ```c sqlite3_temp_directory = "/path/to/custom/temp"; ``` 这允许开发者集中管理和定期清理某个特定目录下的临时文件。 --- #### 方法三:强制删除未清理的临时文件 在极少数情况下,由于进程意外终止等原因,可能导致临时文件残留。此时可采取以下措施: 1. **查找临时文件** SQLite 默认会将临时文件放置在系统的标准临时目录下。可以根据操作系统默认规则定位这些文件。例如,在 Linux 上通常是 `/tmp` 文件夹;而在 Windows 上则是 `%TEMP%` 路径。 2. **编写脚本批量清除** 可以利用脚本来扫描并删除不再使用SQLite 临时文件。以下是 Python 示例代码片段: ```python import os temp_dir = '/tmp' # 替换为实际的临时目录路径 pattern = 'sqlite*.db*' # SQLite 临时文件命名模式 for file_name in os.listdir(temp_dir): if fnmatch.fnmatch(file_name, pattern): try: os.remove(os.path.join(temp_dir, file_name)) print(f"Deleted {file_name}") except Exception as e: print(f"Failed to delete {file_name}: {e}") ``` 注意:此方法需谨慎执行,以免误删其他重要文件。 --- #### 方法四:禁用不必要的临时文件生成 对于性能敏感的应用场景,可通过调整 SQLite 配置减少甚至完全避免临时文件的生成。例如: - 启用内存数据库替代磁盘上的临时表结构: ```sql PRAGMA temp_store = MEMORY; ``` 此命令指示 SQLite 将所有临时对象存储在 RAM 中而不是硬盘上。 - 关闭日志记录功能(仅适用于非持久化需求): ```sql PRAGMA journal_mode = OFF; ``` 上述更改能够显著降低对物理存储的需求,从而间接减少了潜在遗留问题的发生概率。 --- ### 总结 优先推荐采用自动化机制完成临时文件的销毁工作,即保证每次交互结束后均能妥善结束会话关系。只有当发现确实存在孤立实例时才考虑外部手段介入解决该类状况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

界忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值