SQLite 4.9的 OS 接口或“VFS”(十三)

返回:SQLite—系列文章目录   

上一篇:SQLite字节码引擎(十二)

下一篇:SQLite 4.9的虚拟表机制(十四)

1. 引言

本文介绍了 SQLite OS 可移植性层或“VFS” - 模块位于 SQLite 实现堆栈底部 提供跨操作系统的可移植性。

VFS是Virtual File System(虚拟文件系统)的缩写,是一个计算机文件系统的概念。它允许用户在操作系统中通过不同的协议和存储形式访问文件,而不必考虑底层文件系统的物理实现。这些协议可以是本地文件系统、网络文件系统、FTP、WebDAV、数据库等等。它的作用是为不同的文件系统提供一个统一的接口,使得开发人员能够更轻松地处理和使用文件系统。许多操作系统和软件都使用VFS来管理文件系统,例如Linux操作系统、Windows操作系统等。

2. VFS 与 SQLite 其余部分的关系

SQLite库的内部组织可以看作是 右侧显示的模块堆栈。 Tokenizer、Parser 和 Code Generator 组件用于 处理 SQL 语句并将其转换为可执行程序 使用虚拟机语言或字节码。 粗略地说,这前三层实现了 sqlite3_prepare_v2()。前三名生成的字节码 layers 是一个准备好的语句。 虚拟机模块负责运行 SQL 语句 字节码。B-Tree 模块将数据库文件组织成多个 具有有序键和对数性能的键/值存储。 Pager 模块负责加载数据库的页面 文件存入内存,用于实现和控制事务,以及 用于创建和维护阻止数据库的日志文件 崩溃或电源故障后的损坏。 操作系统接口是一个精简抽象,它提供了一组通用的 用于调整 SQLite 以在不同操作系统上运行的例程。 粗略地说,最底层的四层实现了sqlite3_step()。

这篇文章是关于底层的。

操作系统接口 - 也称为“VFS” - 是SQLite的组成部分 跨操作系统可移植。每当任何其他模块 在SQLite中需要与操作进行通信 系统,它们调用 VFS 中的方法。然后,VFS 调用 满足请求所需的特定于操作的代码。 因此,将 SQLite 移植到新的 操作系统只是编写一个新的操作系统接口层的问题 或“VFS”。

3. 多个 VFS

标准 SQLite 源代码树包含用于 unix 的内置 VFS 和窗户。替代 VFS 可以是 使用 sqlite3_vfs_register() 接口在 start-time 或 run-time 添加。

可以同时注册多个 VFS。 每个 VFS 都有唯一的名称。 同一进程中的单独数据库连接可以使用 同时使用不同的 VFS。就此而言,如果单个 数据库连接打开了多个数据库文件,使用 ATTACH 命令,则每个附加的数据库可能都使用 不同的 VFS。

3.1. 标准 Unix VFS

Unix 构建带有多个内置 VFS。默认 VFS 因为 UNIX 被称为“UNIX”,用于大多数应用程序。 在 unix 中可能找到的其他 VFS(取决于编译时 选项)包括:

  1. unix-dotfile - 使用点文件锁定而不是 POSIX 咨询锁。

  2. unix-excl - 获取并持有独占锁 数据库文件,阻止其他进程访问 数据库。还将 wal-index 保持在堆中而不是 共享内存。

  3. unix-none - 所有文件锁定操作都是无操作的。

  4. unix-namedsem - 使用命名信号量进行文件锁定。 仅限 VXWorks。

各种 unix VFS 的区别仅在于它们处理文件锁定的方式 - 它们彼此共享大部分共同的实现,并且 都位于同一个 SQLite 源文件中:os_unix.c。 请注意,除了 “unix” 和 “unix-excl” 之外,各种 unix VFS 都 使用不兼容的锁定实现。如果两个进程正在访问 使用不同 unix VFS 的同一 SQLite 数据库,它们可能 看不到彼此的锁,最终可能会相互干扰, 导致数据库损坏。特别是“unix-none”VFS 根本不会锁定,如果 由两个或多个数据库连接同时使用。 鼓励程序员只使用“unix”或“unix-excl”,除非 有令人信服的理由不这样做。

3.2. 标准 Windows VFS

Windows 版本还附带了多个内置 VFS。默认值 Windows VFS 称为“win32”,用于大多数应用程序。 可能在 Windows 版本上找到的其他 VFS 包括:

  1. win32-longpath - 类似于“win32”,但路径名可以 长度最大为 65534 字节,而路径名的最大长度为 “win32”中的 1040 字节。

  2. Win32-None - 所有文件锁定操作都是无操作的。

  3. win32-longpath-none - “win32-longpath”的组合 和“win32-none” - 支持长路径名,并且全部锁定 操作是无操作的。

与 unix 一样,各种 Windows VFS 的大部分代码都是共享的。

3.3. 指定要使用的 VFS

始终有一个 VFS 是默认的 VFS。在 unix 系统上, “unix”VFS 作为默认值出现,在 Windows 上它是“win32”。 如果未执行其他操作,则将使用新的数据库连接 默认 VFS。

可以通过注册或重新注册 VFS 使用带有第二个参数的 sqlite3_vfs_register() 接口 的 1.因此,如果 (unix) 进程想要始终使用“unix-nolock”VFS 代替“UNIX”,以下代码将起作用:

sqlite3_vfs_register(sqlite3_vfs_find("unix-nolock"), 1);

也可以将备用 VFS 指定为 sqlite3_open_v2() 函数的第 4 个参数。例如:

int rc = sqlite3_open_v2("demo.db", &db, SQLITE_OPEN_READWRITE, "unix-nolock");

最后,如果启用了 URI 文件名,则替代方法 可以使用 URI 上的“vfs=”参数指定 VFS。这种技术 适用于 sqlite3_open()、sqlite3_open16()、sqlite3_open_v2() 和 当新数据库通过 ATTACH 连接到现有数据库连接时。 例如:

ATTACH 'file:demo2.db?vfs=unix-none' AS demo2;

URI 指定的 VFS 具有最高优先级。在那之后 指定为 sqlite3_open_v2() 的第四个参数的 VFS。这 如果未指定 VFS,则使用默认 VFS。

3.4. VFS垫片

从 SQLite 堆栈的上层来看,每个 打开数据库文件仅使用一个 VFS。 但在实践中,特定的 VFS 可能会 只是成为另一个做真正工作的 VFS 的薄包装器。 我们将包装器 VFS 称为“填充码”。

填充码的一个简单示例是“vfstrace”VFS。这是一个 VFS (在 test_vfstrace.c 源文件中实现),用于写入与每个 VFS 方法调用关联的消息 到日志文件中,然后将控制权传递给另一个 VFS 以执行实际操作 工作。

3.5. 其他示例 VFS

以下是公开提供的其他 VFS 实现 SQLite源代码树:

  • appendvfs.c - 此 VFS 允许将 SQLite 数据库附加到某些 其他文件。例如,这可用于追加 SQLite 数据库 到可执行文件的末尾,这样,当运行时,它可以很容易地 找到追加的数据库。命令行 shell 将使用此 VFS(如果使用 --append 选项启动)及其 .archive 命令 将在给定 --append 标志的情况下使用它。

  • test_demovfs.c - 此文件实现了一个名为“demo”的非常简单的 VFS,它使用 POSIX 功能,例如 open(), read(), write(), fsync(), close(), fsync(), fsync(), sleep(), time(), 等等。此 VFS 仅适用于 unix 系统。但事实并非如此 旨在替代默认使用的标准“unix”VFS 在 UNIX 平台上。“演示”VFS刻意保持非常简单 这样它就可以用作学习辅助工具或构建模板 其他 VFS 或用于将 SQLite 移植到新的操作系统。

  • test_quota.c - 此文件实现一个名为“quota”的填充码,该填充码强制执行累积 数据库文件集合的文件大小限制。辅助 接口用于定义“配额组”。配额组是一个 文件集(数据库文件、日志和临时文件),其 名称都与 GLOB 模式匹配。所有文件大小的总和 在每个配额组中跟踪,以及该总和是否超过阈值 为配额组定义后,将调用回调函数。那 回调可以增加阈值,也可以导致操作 这将超过配额,并因SQLITE_FULL错误而失败。此填充码的用途之一用于强制执行 Firefox 中应用程序数据库的资源限制。

  • test_multiplex.c - 此文件实现一个填充码,该填充码允许数据库文件超过 底层文件系统的最大文件大小。这个垫片呈现 SQLite 上六层的接口,使其看起来像 正在使用非常大的文件,而实际上每个这样的大文件 在底层系统上拆分为许多较小的文件。 例如,此填充码已用于允许数据库增长 FAT16 文件系统上大于 2 GB。

  • test_onefile.c - 此文件实现了一个名为“fs”的演示 VFS,它显示了 SQLite 如何 可以在缺少文件系统的嵌入式设备上使用。内容是 直接写入基础媒体。派生自 VFS 演示代码可以由数量有限的小工具使用 闪存,使 SQLite 充当闪存的文件系统 在设备上。

  • test_journal.c - 此文件实现了 SQLite 测试期间使用的填充码,用于验证 数据库和回滚日志按正确的顺序写入,并且 在适当的时间“同步”,以保证数据库 可以随时从断电中恢复硬复位。垫片 检查数据库操作和回滚的几个不变量 日志,并在违反任何这些不变量时引发异常。 反过来,这些不变量确保数据库始终是可恢复的。 使用此填充码运行大量测试用例可提供额外的 保证SQLite数据库不会因意外而损坏 电源故障或设备重置。

  • test_vfs.c - 此文件实现了可用于模拟文件系统故障的填充码。 此填充码在测试期间用于验证 SQLite 的响应是否合理 硬件故障或其他错误情况,例如用完 的文件系统空间,难以在实际系统上进行测试。

在核心 SQLite 源代码中还有其他 VFS 实现 库和可用的扩展。上面的列表并不意味着 详尽无遗,但仅代表可以 使用VFS接口实现。

4. VFS实现

新的 VFS 是通过子类化三个对象来实现的:

  • sqlite3_vfs
  • sqlite3_io_methods
  • sqlite3_file

sqlite3_vfs对象定义 VFS 和内核的名称 实现操作系统接口的方法,例如 如检查文件是否存在、删除文件、创建文件 以及打开和用于读取和/或写入、转换文件名 变成他们的规范形式。sqlite3_vfs对象还包含 从操作系统获取随机性的方法,用于 暂停进程(休眠)并查找当前日期和 时间。

sqlite3_file 对象表示打开的文件。 sqlite3_vfs 的 xOpen 方法在打开文件时构造一个 sqlite3_file 对象。sqlite3_file跟踪 打开文件时的状态。

sqlite3_io_methods对象保存用于交互的方法 使用打开的文件。每个sqlite3_file都包含一个指向 适合于文件的 sqlite3_io_methods 对象 代表。sqlite3_io_methods对象包含要执行的方法 诸如从文件中读取和写入,以截断文件之类的操作, 要刷新对持久性存储的任何更改,请查找 file,以锁定和解锁文件,以及关闭文件并销毁 sqlite3_file对象。

为新 VFS 编写代码涉及构造 sqlite3_vfs对象,然后使用 对 sqlite3_vfs_register() 的调用。VFS 实现还 为 sqlite3_file 和 sqlite3_io_methods 提供子类,但 这些对象不会直接注册到 SQLite。相反,sqlite3_file 对象是从 sqlite3_vfs 的 xOpen 方法返回的,并且 sqlite3_file 对象指向实例 sqlite3_io_methods对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/599005.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac老版本如何升级到最新版本

mac老版本如何升级到最新版本 老macbook升级新版本(Big sur、Monterey) 首先介绍我的电脑的机型及情况: 2015年初的MacBook Air 处理器是1.6Hz 双核Interl Core i5 内存4G 老版本只能升到10.13 想要升到最高版本的原因:想要注册…

解决Xshell连接不上虚拟机

相信有很多同学和我一样遇到这个问题,在网上看了很多教程基本上都让先在虚拟机输入ifconfig命令查看ip地址,弄来弄去最后还是解决不了😭😭,很大概率是我们的虚拟机没有开启网卡,默认Centos是不启用网卡的&a…

麒麟系统ARM安装rabbitmq

简单记录下,信创服务器:麒麟系统,安装rabbitmq的踩坑记录。 本文章参考了很多大佬文章,我整理后提供。 一、安装基础依赖 yum -y install make gcc gcc-c kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel 二、下载…

python gui 实现多个pdf文件合并成一个文件

这是gui截图,汉字都能看懂吧 上代码之前需要安装两个库 pip install PyPDF2 pip install PySimpleGUI然后直接运行代码 import os from PyPDF2 import PdfReader, PdfWriter import PySimpleGUI as sg import tkinter as tk from tkinter import filedialogdef Ge…

八数码问题(bfs)

方式一:string存储状态 题目传送门:845. 八数码 - AcWing题库 BFS适用于边权为1的最短路问题 ,而这题要求最少的交换次数,将每一次的九宫格状态当作一个“状态结点”,由当前这个结点可以扩展出其它状态【即 x 可以与其…

基于R语言BIOMOD2模型的物种分布模拟

随着生物多样性全球大会的举办,不论是管理机构及科研单位、高校都在积极准备,根据国家林草局最新工作指示,我国将积极整合、优化自然保护地,加快推进国家公园体制试点,构建以国家公园为主体的自然保护地体系。针对我国…

layui在上传多图时,allDone方法只是在第一次全部成功时调用了

问题点:在使用layui框架做多张图片上传时,遇见只有第一次操作上传图片时,触发了allDone全部上传成功的方法,后面再添加图片时,就不会调用这个方法 原因:是因为我删除了 choose 方法,并且也没有将…

flutter升级3.10.6Xcode构建报错

flutter sdk 升级Xcode报错收集,错误信息如下: Error (Xcode): Cycle inside Runner; building could produce unreliable results.没问题版本信息: Xcode:15.3 flutter sdk :3.7.12 dart sdk:2.19.6 …

真实的招生办对话邮件及美国高校官网更新的反 AI 政策

这两年 ChatGPT 的热度水涨船高,其编写功能强大,且具备强大的信息整合效果,所以呈现的内容在一定程度上具备可读性。 那么,美国留学文书可以用 ChatGPT 写吗?使用是否有风险?外网博主 Kushi Uppu 在这个申…

自动化高并发抓取淘宝平台商品数据(内附接入key密钥API响应示例)

通过API接口(接入key,密钥),可以获取商品的标题、价格、图片、描述等详细信息。 item_get 获得淘宝商品详情item_get_pro 获得淘宝商品详情高级版item_review 获得淘宝商品评论item_fee 获得淘宝商品快递费用item_password 获得…

设计模式浅析(十) ·设计模式之迭代器组合模式

设计模式浅析(十) 设计模式之迭代器&组合模式 日常叨逼叨 java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷😁😁 案例 有两家门店,门店A呢只提供早餐,门店B呢只提供午…

mysqldump: Got error: 1049: Unknown database ‘root‘ when selecting the datab

1.问题描述 MySQL版本号:MySQL Server 8.3MySQL持久化到处数据库结构及数据 mysqldump: Got error: 1049: Unknown database root when selecting the datab2.问题解决 cmd 切换本地路径 cd /d D:\Program Files\MySQL\MySQL Server 8.3\bin执行数据库备份命令 …