相关文章推荐
帅气的灭火器  ·  Database re-creation ...·  3 月前    · 
儒雅的甘蔗  ·  SQLite error no such ...·  3 月前    · 
发财的移动电源  ·  Urbackup Server ...·  3 月前    · 
聪明伶俐的馒头  ·  Urbackup Server ...·  3 月前    · 
强悍的毛豆  ·  Python SQLite - ...·  2 月前    · 
打篮球的汽水  ·  Mockito ...·  2 年前    · 
害羞的冲锋衣  ·  2.3 ...·  2 年前    · 
咆哮的黄豆  ·  MobaXterm卡在 ...·  3 年前    · 

1. 概述

对于大多数用途,SQLite 可以使用默认的编译选项正常构建。但是,如果需要,下面记录的编译时选项可用于 省略 SQLite 功能 (从而导致 编译后的库大小更小 )或更改某些参数的 默认值

我们已尽一切努力确保各种编译选项组合能够和谐地工作并生成可工作的库。但是,强烈建议在使用使用非标准编译选项构建的 SQLite 库之前,执行 SQLite 测试套件以检查错误。

2. 推荐的编译时选项

以下编译时选项推荐用于能够使用它们的应用程序,以最大程度地减少 SQLite 使用的 CPU 周期和内存字节数。并非所有这些编译时选项都可用于每个应用程序。例如,SQLITE_THREADSAFE=0 选项仅可用于一次从未从多个线程访问 SQLite 的应用程序。SQLITE_OMIT_PROGRESS_CALLBACK 选项仅可用于不使用 sqlite3_progress_handler() 接口的应用程序。依此类推。

无法测试 SQLite 的每种可能的编译时选项组合。但以下一组编译时选项是一种始终经过全面测试的配置。

  1. SQLITE_DQS=0 。此设置禁用 双引号字符串文字 的错误功能。

  2. SQLITE_THREADSAFE=0 。设置 -DSQLITE_THREADSAFE=0 会导致 SQLite 中的所有互斥锁和线程安全逻辑被省略。这是导致 SQLite 运行速度提高约 2% 且库大小减少约 2% 的单个编译时选项。但缺点是,使用此编译时选项意味着 SQLite 永远不能被多个线程同时使用,即使每个线程都有自己的数据库连接。

  3. SQLITE_DEFAULT_MEMSTATUS=0 。此设置导致跟踪内存用量的 sqlite3_status() 接口被禁用。这有助于 sqlite3_malloc() 例程运行得更快,并且由于 SQLite 在内部使用 sqlite3_malloc() ,因此这有助于使整个库运行得更快。

  4. SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 。为了在断电后获得最大的数据库安全性,建议设置 PRAGMA synchronous=FULL 。但是,在 WAL 模式 下,使用 PRAGMA synchronous=NORMAL 可以保证完整的数据库完整性。在 WAL 模式 下使用 PRAGMA synchronous=NORMAL 时,最近对数据库的更改可能会因断电而回滚,但数据库不会损坏。此外,在 WAL 模式下使用 synchronous=NORMAL 进行事务提交的速度比使用默认的 synchronous=FULL 快得多。出于这些原因,建议在切换到 WAL 模式时将 synchronous 设置从 FULL 更改为 NORMAL。此编译时选项将实现此目的。

  5. SQLITE_LIKE_DOESNT_MATCH_BLOBS 。从历史上看,SQLite 允许将 BLOB 操作数用于 LIKE GLOB 运算符。但是,将 BLOB 作为 LIKE GLOB 的操作数会使 LIKE 优化 变得复杂并降低速度。设置此选项意味着,如果任一操作数为 BLOB,则 LIKE 和 GLOB 运算符始终返回 FALSE。这简化了 LIKE 优化 的实现,并允许使用 LIKE 优化 的查询运行得更快。

  6. SQLITE_MAX_EXPR_DEPTH=0 。将最大表达式解析树深度设置为零会禁用对表达式解析树深度的所有检查,这可以简化代码从而导致更快的执行速度,并有助于解析树使用更少的内存。

  7. SQLITE_OMIT_DECLTYPE 。通过省略(很少需要)从查询结果集中返回列的声明类型的能力,可以使 预处理语句 消耗更少的内存。

  8. SQLITE_OMIT_DEPRECATED 。省略已弃用的接口和功能不会帮助 SQLite 运行得更快。但是它会减少库占用空间。这是正确的做法。

  9. SQLITE_OMIT_PROGRESS_CALLBACK 。进度处理程序回调计数器必须在 字节码引擎 的内循环中进行检查。通过省略此接口,可以从 字节码引擎 的内循环中删除一个条件,从而帮助 SQL 语句运行得略快。

  10. SQLITE_OMIT_SHARED_CACHE 。省略使用 共享缓存 的可能性允许消除代码性能关键部分中的许多条件。这可以显着提高性能。

  11. SQLITE_USE_ALLOCA 。在支持 alloca() 的系统上,利用 alloca() 为在单个函数中使用动态分配临时堆栈空间。如果没有此选项,则会从堆中分配临时空间。

  12. SQLITE_OMIT_AUTOINIT 。SQLite 库需要使用对 sqlite3_initialize() 的调用进行初始化,然后才能使用某些接口。此初始化通常在第一次需要时自动发生。但是,使用 SQLITE_OMIT_AUTOINIT 选项会省略自动初始化。这有助于许多 API 调用运行得更快(因为它们不必检查初始化是否已发生,然后在之前未调用初始化的情况下运行初始化),但这也意味着应用程序必须手动调用 sqlite3_initialize() 。如果 SQLite 使用 -DSQLITE_OMIT_AUTOINIT 进行编译,并且在未首先调用 sqlite3_initialize() 的情况下调用了 sqlite3_malloc() sqlite3_vfs_find() sqlite3_open() 等例程,则可能的结果是段错误。

  13. SQLITE_STRICT_SUBTYPE=1 。此选项会导致如果未具有 SQLITE_RESULT_SUBTYPE 属性的应用程序定义函数调用 sqlite3_result_subtype() 接口,则引发错误。除非使用 SQLITE_RESULT_SUBTYPE 属性注册该函数,否则 sqlite3_result_subtype() 接口无法可靠地工作。此编译时选项旨在尽早提请开发人员注意此问题。

当使用上述所有推荐的编译时选项时,SQLite 库将大约缩小 3%,并使用约 5% 的 CPU 周期。因此,这些选项不会产生巨大差异。但在某些设计情况下,每一小部分都有帮助。

库级配置选项(例如上面列出的选项)可以选择在客户端头文件中定义。定义 SQLITE_CUSTOM_INCLUDE=myconfig.h(不带引号)将导致 sqlite3.c 在编译过程的早期包含 myconfig.h,使客户端能够自定义标志,而无需显式地将所有标志传递给编译器。

3. 平台配置

_HAVE_SQLITE_CONFIG_H

如果定义了 _HAVE_SQLITE_CONFIG_H 宏,则 SQLite 源代码将尝试 #include 一个名为“sqlite_cfg.h”的文件。“sqlite_cfg.h”文件通常包含其他配置选项,尤其是由 autoconf 脚本生成的“HAVE_ INTERFACE ”类型选项。请注意,此标头仅用于平台级配置,不用于库级配置。要在自定义标头中设置 SQLite 级配置标志,请定义 SQLITE_CUSTOM_INCLUDE=myconfig.h,如上一节所述。

HAVE_FDATASYNC

如果 HAVE_FDATASYNC 编译时选项为真,则 unix 系统的默认 VFS 将尝试在适当的情况下使用 fdatasync() 而不是 fsync()。如果此标志不存在或为假,则始终使用 fsync()。

HAVE_GMTIME_R

如果 HAVE_GMTIME_R 选项为真,并且如果 SQLITE_OMIT_DATETIME_FUNCS 为真,则 CURRENT_TIME、CURRENT_DATE 和 CURRENT_TIMESTAMP 关键字将使用线程安全的“gmtime_r()”接口而不是“gmtime()”。在通常情况下,如果 SQLITE_OMIT_DATETIME_FUNCS 未定义或为假,则内置的 日期和时间函数 用于实现 CURRENT_TIME、CURRENT_DATE 和 CURRENT_TIMESTAMP 关键字,并且永远不会调用 gmtime_r() 或 gmtime()。

HAVE_ISNAN

如果 HAVE_ISNAN 选项为真,则 SQLite 调用系统库 isnan() 函数来确定双精度浮点值是否为 NaN。如果 HAVE_ISNAN 未定义或为假,则 SQLite 替换其自己的 isnan() 自制实现。

HAVE_LOCALTIME_R

如果 HAVE_LOCALTIME_R 选项为真,则 SQLite 使用线程安全的 localtime_r() 库例程而不是 localtime() 来帮助实现内置 日期和时间函数 localtime 修饰符

HAVE_LOCALTIME_S

如果 HAVE_LOCALTIME_S 选项为真,则 SQLite 使用线程安全的 localtime_s() 库例程而不是 localtime() 来帮助实现内置 日期和时间函数 localtime 修饰符

HAVE_MALLOC_USABLE_SIZE

如果 HAVE_MALLOC_USABLE_SIZE 选项为真,则 SQLite 尝试使用 malloc_usable_size() 接口查找从标准库 malloc() 或 realloc() 例程获得的内存分配的大小。此选项仅适用于使用标准库 malloc() 的情况。在 Apple 系统上,使用“zone malloc”,因此此选项不适用。当然,如果应用程序使用 SQLITE_CONFIG_MALLOC 提供自己的 malloc 实现,则此选项无效。

如果省略了 HAVE_MALLOC_USABLE_SIZE 选项或该选项为假,则 SQLite 使用围绕系统 malloc() 和 realloc() 的包装器,将每个分配扩大 8 个字节并将分配的大小写入初始 8 个字节,然后 SQLite 还实现了自己的 malloc_usable_size() 自制版本,该版本查询该 8 字节前缀以查找分配大小。这种方法有效,但不是最佳方法。鼓励应用程序尽可能使用 HAVE_MALLOC_USABLE_SIZE。

HAVE_STRCHRNUL

如果 HAVE_STRCHRNUL 选项为真,则 SQLite 使用 strchrnul() 库函数。如果此选项不存在或为假,则 SQLite 替换其自己的 strchrnul() 自制实现。

HAVE_UTIME

如果 HAVE_UTIME 选项为真,则内置但非标准的“unix-dotfile”VFS 将使用 utime() 系统调用而不是 utimes() 来设置锁文件上的上次访问时间。

SQLITE_BYTEORDER= (0|1234|4321)

SQLite 需要知道目标 CPU 的原生字节序是大端还是小端。SQLITE_BYTEORDER 预处理器对于大端机器设置为 4321,对于小端机器设置为 1234,或者可以设置为 0,表示字节序必须在运行时确定。代码中有一些 #ifdef 用于自动为所有常见平台和编译器设置 SQLITE_BYTEORDER。但是,在为模糊的目标编译 SQLite 时,适当地设置 SQLITE_BYTEORDER 可能会有优势。如果目标字节序无法在编译时确定,则 SQLite 会回退到执行运行时检查,这些检查始终有效,但会带来少量性能损失。

4. 设置默认参数值的选项

SQLITE_DEFAULT_AUTOMATIC_INDEX= <0 或 1>

此宏确定为新打开的 PRAGMA automatic_index 数据库连接 的初始设置。对于 3.7.17 及之前的 SQLite 所有版本,如果省略此编译时选项,则通常会为新的数据库连接启用自动索引。但是,这可能会在 SQLite 的未来版本中发生变化。

另请参阅: SQLITE_OMIT_AUTOMATIC_INDEX

SQLITE_DEFAULT_AUTOVACUUM= <0 或 1 或 2>

此宏确定 SQLite 是否默认创建具有 auto_vacuum 标志设置为 OFF (0)、FULL (1) 或 INCREMENTAL (2) 的数据库。默认值为 0,表示数据库创建时自动真空关闭。无论如何, PRAGMA auto_vacuum 命令可以覆盖编译时默认值。

SQLITE_DEFAULT_CACHE_SIZE= <N>

此宏设置每个附加数据库的页面缓存的最大默认大小。正值表示限制为 N 页。如果 N 为负数,则表示将缓存大小限制为 -N*1024 字节。可以使用 PRAGMA cache_size 命令覆盖建议的最大缓存大小。默认值为 -2000,转换为每个缓存最大 2048000 字节。

SQLITE_DEFAULT_FILE_FORMAT= <1 或 4>

SQLite 创建新数据库文件时使用的默认 模式格式编号 由此宏设置。模式格式都非常相似。格式 1 和 4 之间的区别在于格式 4 理解 降序索引 并且对布尔值的编码更紧凑。

自 3.3.0 版(2006-01-10)以来的所有 SQLite 版本都可以读取和写入 1 到 4 之间的任何模式格式。但较旧版本的 SQLite 可能无法读取大于 1 的格式。因此,为了使较旧版本的 SQLite 能够读取和写入新版本 SQLite 创建的数据库文件,对于 3.7.9 版(2011-11-01)之前的 SQLite 版本,默认模式格式设置为 1。从 3.7.10 版 (2012-01-16)开始,默认模式格式为 4。

可以使用 PRAGMA legacy_file_format 命令在运行时设置新数据库的模式格式编号。

SQLITE_DEFAULT_FILE_PERMISSIONS= N

Unix 下新创建的数据库文件的默认数字文件权限。如果未指定,则默认为 0644,这意味着文件全局可读,但只有创建者可写。

SQLITE_DEFAULT_FOREIGN_KEYS= <0 或 1>

此宏确定是否默认启用或禁用新数据库连接的 外键约束 强制执行。每个数据库连接始终可以使用 foreign_keys pragma 在运行时打开和关闭外键约束的强制执行。外键约束的强制执行通常默认关闭,但如果此编译时参数设置为 1,则默认情况下会打开外键约束的强制执行。

SQLITE_DEFAULT_MMAP_SIZE= N

此宏设置每个打开的数据库文件用于内存映射 I/O 的内存量的默认限制。如果 N 为零,则默认情况下禁用内存映射 I/O。可以使用 sqlite3_config ( SQLITE_CONFIG_MMAP_SIZE ) 调用在启动时修改此编译时限制和 SQLITE_MAX_MMAP_SIZE ,或者使用 mmap_size pragma 在运行时修改。

SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT= <字节>

此选项设置 回滚日志 文件在 持久化日志模式 独占锁定模式 中的大小限制,以及 WAL 模式 中预写日志文件的大小。当省略此编译时选项时,回滚日志或预写日志的大小没有上限。可以使用 journal_size_limit pragma 在运行时更改日志文件大小限制。

SQLITE_DEFAULT_LOCKING_MODE= <1 或 0>

如果设置为 1,则默认 locking_mode 设置为 EXCLUSIVE。如果省略或设置为 0,则默认 locking_mode 为 NORMAL。

SQLITE_DEFAULT_LOOKASIDE= SZ,N

备用内存分配器 内存池的默认大小设置为每个 SZ 字节 N 个条目。可以使用 sqlite3_config ( SQLITE_CONFIG_LOOKASIDE ) 在启动时修改此设置,以及/或者在使用 sqlite3_db_config (db, SQLITE_DBCONFIG_LOOKASIDE ) 打开每个 数据库连接 时修改。

SQLITE_DEFAULT_MEMSTATUS= <1 或 0>

此宏用于确定是否默认可以使用使用 sqlite3_config() 的 SQLITE_CONFIG_MEMSTATUS 参数启用和禁用的功能。默认值为 1( SQLITE_CONFIG_MEMSTATUS 相关功能已启用)。

sqlite3_memory_used() sqlite3_memory_highwater() 接口、 sqlite3_status64 ( SQLITE_STATUS_MEMORY_USED ) 接口以及 SQLITE_MAX_MEMORY 编译时选项在禁用内存使用跟踪时均不起作用。

SQLITE_DEFAULT_PCACHE_INITSZ= N

当未使用 SQLITE_CONFIG_PAGECACHE 配置选项并且页面缓存的内存是从 sqlite3_malloc() 获取时,此宏确定页面缓存模块最初分配的页面数。此宏设置的页面数在一个分配中分配,这减少了内存分配器的负载。

SQLITE_DEFAULT_PAGE_SIZE= <字节>

此宏用于设置创建数据库时使用的默认页面大小。分配的值必须是 2 的幂。默认值为 4096。可以使用 PRAGMA page_size 命令在运行时覆盖编译时默认值。

SQLITE_DEFAULT_SYNCHRONOUS= <0-3>

此宏确定 PRAGMA synchronous 设置的默认值。如果在编译时未覆盖,则默认设置为 2(FULL)。

SQLITE_DEFAULT_WAL_SYNCHRONOUS= <0-3>

此宏确定以 WAL 模式 打开的数据库文件的 PRAGMA synchronous 设置的默认值。如果在编译时未覆盖,则此值与 SQLITE_DEFAULT_SYNCHRONOUS 相同。

如果 SQLITE_DEFAULT_WAL_SYNCHRONOUS 与 SQLITE_DEFAULT_SYNCHRONOUS 不同,并且如果应用程序尚未使用 PRAGMA synchronous 语句修改数据库文件的同步设置,则当数据库连接第一次切换到 WAL 模式时,同步设置将更改为 SQLITE_DEFAULT_WAL_SYNCHRONOUS 定义的值。如果在编译时未覆盖 SQLITE_DEFAULT_WAL_SYNCHRONOUS 值,则它将始终与 SQLITE_DEFAULT_SYNCHRONOUS 相同,因此永远不会发生自动同步设置更改。

SQLITE_DEFAULT_WAL_AUTOCHECKPOINT= <页数>

此宏设置 WAL 自动检查点 功能的默认页面计数。如果未指定,则默认页面计数为 1000。

SQLITE_DEFAULT_WORKER_THREADS= N

此宏设置 SQLITE_LIMIT_WORKER_THREADS 参数的默认值。 SQLITE_LIMIT_WORKER_THREADS 参数设置单个 预准备语句 为协助查询而启动的辅助线程的最大数量。如果未指定,则默认最大值为 0。此处设置的值不能超过 SQLITE_MAX_WORKER_THREADS

SQLITE_DQS= N

此宏确定 SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML 的默认值,而这些值又决定了 SQLite 如何处理每个 双引号字符串文字 。“DQS”名称代表“ D ouble- Q uoted S tring”。 N 参数应为整数 0、1、2 或 3。

SQLITE_DQS 允许使用双引号字符串 备注
在 DDL 中 在 DML 中
3 默认
2
1
0 推荐

推荐的设置是 0,表示在所有上下文中都不允许使用双引号字符串。但是,默认设置为 3,以最大程度地与旧版应用程序兼容。

SQLITE_EXTRA_DURABLE

SQLITE_EXTRA_DURABLE 编译时选项用于导致默认 PRAGMA synchronous 设置为 EXTRA,而不是 FULL。此选项不再受支持。请改用 SQLITE_DEFAULT_SYNCHRONOUS=3

SQLITE_FTS3_MAX_EXPR_DEPTH= N

此宏设置与 FTS3 FTS4 全文索引中 MATCH 运算符的右侧对应的搜索树的最大深度。全文搜索使用递归算法,因此树的深度受到限制,以防止使用过多的堆栈空间。默认限制为 12。此限制足以处理 MATCH 运算符右侧最多 4095 个搜索词,并且它将堆栈空间使用量控制在 2000 字节以下。

对于普通的 FTS3/FTS4 查询,搜索树深度大约是 MATCH 运算符右侧术语数量的以 2 为底的对数。但是,对于 短语查询 NEAR 查询 ,搜索树深度与右侧术语的数量成线性关系。因此,默认深度限制 12 足以处理 MATCH 上最多 4095 个普通术语,但它仅足以处理 11 或 12 个短语或 NEAR 术语。即便如此,默认值对于大多数应用程序来说也绰绰有余。

SQLITE_JSON_MAX_DEPTH= N

此宏设置 JSON 对象和数组的最大嵌套深度。默认值为 1000。

JSON SQL 函数 使用 递归下降解析器 。这意味着深度嵌套的 JSON 可能需要大量堆栈空间才能进行解析。在堆栈空间有限的系统上,可以将 SQLite 编译为大大降低的最大 JSON 嵌套深度,以避免出现堆栈溢出的可能性,即使来自恶意输入也是如此。即使对于最复杂的真实世界 JSON,10 或 20 的值通常也足够了。

SQLITE_LIKE_DOESNT_MATCH_BLOBS

此编译时选项会导致 LIKE 运算符在任一操作数为 BLOB 时始终返回 False。 LIKE 的默认行为是在进行比较之前将 BLOB 操作数转换为 TEXT。

此编译时选项使 SQLite 在处理使用 LIKE 运算符的查询时运行效率更高,但代价是破坏向后兼容性。但是,向后兼容性的破坏可能仅仅是技术上的。在 LIKE 处理逻辑中存在一个长期存在的错误(请参阅 https://www.sqlite.org/src/info/05f43be8fdda9f ),导致它在 BLOB 操作数的情况下出现错误行为,并且在近 10 年的活跃使用中没有人注意到该错误。因此,对于大多数用户来说,启用此编译时选项可能是安全的,从而可以节省 LIKE 查询上的一点 CPU 时间。

此编译时选项仅影响 SQL LIKE 运算符,对 sqlite3_strlike() C 语言接口没有影响。

SQLITE_MAX_MEMORY= N

此选项将 SQLite 从 malloc() 请求的内存总量限制为 N 字节。SQLite 尝试分配新内存的任何操作,如果会导致 SQLite 持有的所有分配的总和超过 N 字节,都将导致内存不足错误。这是一个硬性上限。另请参阅 sqlite3_soft_heap_limit() 接口。

此选项是对分配的 内存量的限制。有关单个内存分配允许的内存量的限制,请参阅 SQLITE_MAX_ALLOCATION_SIZE 选项。

此限制仅在可以通过 sqlite3_memory_used() sqlite3_status64 ( SQLITE_STATUS_MEMORY_USED ) 接口获得内存使用统计信息时才有效。如果没有该内存使用信息,SQLite 将无法知道何时即将超出限制,因此无法阻止过多的内存分配。内存使用跟踪默认情况下处于启用状态,但可以通过使用 SQLITE_DEFAULT_MEMSTATUS 选项在编译时禁用,或通过使用 sqlite3_config ( SQLITE_CONFIG_MEMSTATUS ) 在启动时禁用。

SQLITE_MAX_MMAP_SIZE= N

此宏为任何单个数据库可以使用内存映射 I/O 的地址空间量设置硬性上限。将此值设置为 0 将完全禁用内存映射 I/O,并导致与内存映射 I/O 相关的逻辑从构建中省略。此选项不会更改默认的内存映射 I/O 地址空间大小(由 SQLITE_DEFAULT_MMAP_SIZE 或 sqlite3_config( SQLITE_CONFIG_MMAP_SIZE ) 设置)或运行时内存映射 I/O 地址空间大小(由 sqlite3_file_control( SQLITE_FCNTL_MMAP_SIZE ) 或 PRAGMA mmap_size 设置),只要这些其他设置小于此处定义的最大值。

SQLITE_MAX_SCHEMA_RETRY= N

每当数据库模式更改时,预准备语句都会自动重新准备以适应新的模式。这里存在一个竞争条件,即如果一个线程不断更改模式,则另一个线程可能会在预准备语句的重新解析和重新准备上循环,并且永远无法完成任何实际工作。此参数通过强制旋转线程在尝试重新编译预准备语句的固定次数后放弃来防止无限循环。默认设置为 50,对于大多数应用程序来说绰绰有余。

SQLITE_MAX_WORKER_THREADS= N

sqlite3_limit (db, SQLITE_LIMIT_WORKER_THREADS ,N) 设置设置上限,该设置确定单个 预准备语句 将用于帮助进行 CPU 密集型计算(主要是排序)的辅助线程的最大数量。另请参阅 SQLITE_DEFAULT_WORKER_THREADS 选项。

SQLITE_MEMDB_DEFAULT_MAXSIZE= N

设置使用 sqlite3_deserialize() 创建的内存数据库的默认大小限制(以字节为单位)。这仅仅是默认值。可以使用 sqlite3_config ( SQLITE_CONFIG_MEMDB_MAXSIZE ,N) 在启动时更改限制,或使用 SQLITE_FCNTL_SIZE_LIMIT 文件控制 在运行时为各个数据库更改限制。如果未指定默认值,则使用 1073741824。

SQLITE_MINIMUM_FILE_DESCRIPTOR= N

unix VFS 永远不会使用小于 N 的文件描述符。 N 的默认值为 3。

避免使用编号较低的文件描述符是为了防止意外的数据库损坏。例如,如果数据库文件是使用文件描述符 2 打开的,然后断言失败并调用 write(2,...),则很可能会通过用断言错误消息覆盖数据库文件的一部分来导致数据库损坏。仅使用值较高的文件描述符可以避免此潜在问题。可以通过将此编译时选项设置为 0 来禁用防止使用编号较低的文件描述符的保护。

SQLITE_POWERSAFE_OVERWRITE= <0 或 1>

此选项更改了对 unix 和 windows VFSes 的底层文件系统的 电源安全覆盖 的默认假设。将 SQLITE_POWERSAFE_OVERWRITE 设置为 1 会导致 SQLite 假设应用程序级写入不能更改写入字节范围之外的字节,即使写入发生在电源丢失之前。当 SQLITE_POWERSAFE_OVERWRITE 设置为 0 时,SQLite 假设与已写入字节位于同一扇区的其他字节可能会因电源丢失而更改或损坏。

SQLITE_PRINTF_PRECISION_LIMIT= N

此选项限制 printf() SQL 函数 和其他 C 语言字符串格式化函数(如 sqlite3_mprintf() sqlite3_str_appendf() )的替换的最大宽度和精度。这反过来可以防止恶意或故障脚本通过调用以下格式来使用过多的内存: printf('%*s',2147483647,'hi') "。 N 的值大约为 100000 通常就足够了。

printf() SQL 函数 sqlite3_limit() SQLITE_LIMIT_LENGTH 限制。因此,宽度或精度超过 SQLITE_LIMIT_LENGTH 的任何 printf() 结果都将导致 SQLITE_TOOBIG 错误。但是,printf() 函数的底层格式化是由一个子例程完成的,该子例程无法访问 SQLITE_LIMIT_LENGTH。因此,底层格式化完成到可能远大于 SQLITE_LIMIT_LENGTH 的内存分配中,并且仅在所有格式化完成后才执行 SQLITE_LIMIT_LENGTH 检查。因此,可能会存在一个超出 SQLITE_LIMIT_LENGTH 的瞬态缓冲区。SQLITE_PRINTF_PRECISION_LIMIT 选项是另一项检查,它可以防止在底层格式化子例程内部使用过大的瞬态缓冲区大小,这在 SQLITE_LIMIT_LENGTH 检查之前。

注意不要将 SQLITE_PRINTF_PRECISION_LIMIT 设置得太低。SQLite 使用其 内置 printf() 功能来格式化存储在 sqlite_schema 表 中的 CREATE 语句的文本。因此,SQLITE_PRINTF_PRECISION_LIMIT 至少应与您可能遇到的最大表、索引、视图或触发器定义一样大。

如果宽度或精度超过 SQLITE_PRINTF_PRECISION_LIMIT,则不会引发错误。而是会静默截断较大的宽度或精度。

SQLITE_PRINTF_PRECISION_LIMIT 的默认值为 2147483647 (0x7fffffff)。

SQLITE_QUERY_PLANNER_LIMIT= N

作为查询计划过程的一部分,SQLite 枚举索引和 WHERE 子句约束的所有可用组合。对于某些病态查询,这些索引和约束组合的数量可能非常大,从而导致查询计划程序的性能下降。SQLITE_QUERY_PLANNER_LIMIT 值(与相关的 SQLITE_QUERY_PLANNER_LIMIT_INCR 设置一起)限制了查询计划程序将考虑的索引和约束组合的数量,以防止查询计划程序使用过多的 CPU 时间。SQLITE_QUERY_PLANNER_LIMIT 的默认值设置得足够高,因此在现实世界的查询中永远不会达到。查询计划程序搜索限制仅适用于专门设计为使用过多的计划时间的查询。

SQLITE_QUERY_PLANNER_LIMIT_INCR= N

SQLITE_QUERY_PLANNER_LIMIT 选项为查询计划程序考虑的索引和约束组合的最大数量设置初始基线值。在处理联接的每个表之前,基线查询计划程序限制将增加 SQLITE_QUERY_PLANNER_LIMIT_INCR,以便保证每个表都能够向优化器提出至少一些索引和约束组合,即使联接的先前表已用尽基线限制。此编译时选项和 SQLITE_QUERY_PLANNER_LIMIT 选项的默认值都设置得足够高,因此在现实世界的查询中应该永远不会达到。

SQLITE_REVERSE_UNORDERED_SELECTS

此选项导致 PRAGMA reverse_unordered_selects 设置默认启用。启用后,缺少 ORDER BY 子句的 SELECT 语句将以相反的顺序运行。

此选项可用于检测应用程序何时(错误地)假设没有 ORDER BY 子句的 SELECT 中行的顺序始终相同。

SQLITE_SORTER_PMASZ= N

如果通过 PRAGMA threads 设置启用了多线程处理,则当要排序的内容量超过由 cache_size 和由 SQLITE_CONFIG_PMASZ 启动时选项确定的 PMA 大小的最小值时,排序操作将尝试启动辅助线程。此编译时选项为 SQLITE_CONFIG_PMASZ 启动时选项设置默认值。默认值为 250。

SQLITE_STMTJRNL_SPILL= N

SQLITE_STMTJRNL_SPILL 编译时选项确定 SQLITE_CONFIG_STMTJRNL_SPILL 启动时设置的默认设置。该设置确定 语句日志 从内存移动到磁盘的大小阈值。

SQLITE_WIN32_MALLOC

此选项启用使用 Windows 堆 API 函数进行内存分配,而不是使用标准库 malloc() 和 free() 例程。

YYSTACKDEPTH= <最大深度>

此宏设置 SQLite 中 SQL 解析器使用的 LALR(1) 堆栈的最大深度。默认值为 100。典型的应用程序将使用不到 20 个堆栈级别。其应用程序包含需要超过 100 个 LALR(1) 堆栈条目的 SQL 语句的开发人员应该认真考虑重构其 SQL,因为它很可能超出了任何人类理解的能力。

5. 设置大小限制的选项

有一些编译时选项将设置 SQLite 中各种结构的大小上限。编译时选项通常设置一个硬性上限,可以使用 sqlite3_limit() 接口在运行时为各个 数据库连接 更改该上限。

设置上限的编译时选项 在单独的文档中进行了说明 。以下是可用设置的列表

  • SQLITE_MAX_ATTACHED
  • SQLITE_MAX_COLUMN
  • SQLITE_MAX_COMPOUND_SELECT
  • SQLITE_MAX_EXPR_DEPTH
  • SQLITE_MAX_FUNCTION_ARG
  • SQLITE_MAX_LENGTH
  • SQLITE_MAX_LIKE_PATTERN_LENGTH
  • SQLITE_MAX_PAGE_COUNT
  • SQLITE_MAX_SQL_LENGTH
  • SQLITE_MAX_VARIABLE_NUMBER

    也有一些大小限制无法使用 sqlite3_limit() 进行修改。例如,请参阅

    此外,还提供了五个额外的 VFS 实现以及默认实现。通过在调用 sqlite3_open_v2() 时指定其中一个额外的 VFS 实现,应用程序可以绕过文件系统检测逻辑并显式选择上述锁定样式之一。五个额外的 VFS 实现分别称为“unix-posix”、“unix-afp”、“unix-flock”、“unix-dotfile”和“unix-none”。

  • SQLITE_ENABLE_MEMORY_MANAGEMENT

    此选项向 SQLite 添加额外的逻辑,使其能够根据请求释放未使用的内存。必须启用此选项才能使 sqlite3_release_memory() 接口正常工作。如果不使用此编译时选项,则 sqlite3_release_memory() 接口将成为无操作。

    SQLITE_ENABLE_MEMSYS3

    此选项包含 SQLite 中的代码,该代码实现了备用内存分配器。仅当 sqlite3_config() SQLITE_CONFIG_HEAP 选项用于提供一个大块内存(所有内存分配都来自该内存)时,才会使用此备用内存分配器。MEMSYS3 内存分配器使用一种混合分配算法,该算法以 dlmalloc() 为蓝本。一次只能启用 SQLITE_ENABLE_MEMSYS3 或 SQLITE_ENABLE_MEMSYS5 中的一个。

    SQLITE_ENABLE_MEMSYS5

    此选项包含 SQLite 中的代码,该代码实现了备用内存分配器。仅当 sqlite3_config() SQLITE_CONFIG_HEAP 选项用于提供一个大块内存(所有内存分配都来自该内存)时,才会使用此备用内存分配器。MEMSYS5 模块将所有分配四舍五入到下一个 2 的幂,并使用一种首次适配、伙伴分配算法,该算法在某些操作约束下提供了针对碎片和崩溃的强有力保证。

    SQLITE_ENABLE_NORMALIZE

    此选项包含 sqlite3_normalized_sql() API。

    SQLITE_ENABLE_NULL_TRIM

    此选项启用一项优化,该优化会省略行末尾的 NULL 列,从而节省磁盘空间。

    使用此选项启用的数据库无法被 SQLite 3.1.6(2005-03-17)及更早版本读取。此外,使用此选项启用的数据库容易触发 e6e962d6b0f06f46 错误 sqlite3_blob_reopen() 接口。由于这些原因,此优化默认处于禁用状态。但是,此优化可能会在 SQLite 的未来版本中默认启用。

    SQLITE_ENABLE_OFFSET_SQL_FUNC

    此选项启用对 sqlite_offset(X) SQL 函数的支持。

    sqlite_offset(X) SQL 函数需要 B 树存储引擎上的新接口、运行 SQL 语句的 虚拟机 中的新操作码以及代码生成器关键路径中的新条件。为了避免在不需要 sqlite_offset(X) 实用程序的应用程序中出现此开销,该函数默认处于禁用状态。

    SQLITE_ENABLE_PREUPDATE_HOOK

    此选项启用 几个新的 API ,这些 API 在对 rowid 表 进行任何更改之前提供回调。回调可用于记录更改发生之前行的状态。

    预更新挂钩的操作类似于 更新挂钩 ,不同之处在于回调是在更改之前调用的,而不是之后调用的,并且除非使用此编译时选项,否则会省略预更新挂钩接口。

    最初添加预更新挂钩接口是为了支持 session 扩展。

    SQLITE_ENABLE_QPSG

    此选项会导致 查询计划程序稳定性保证 (QPSG)默认开启。通常情况下,QPSG 是关闭的,必须使用 sqlite3_db_config() 接口的 SQLITE_DBCONFIG_ENABLE_QPSG 选项在运行时激活它。

    SQLITE_ENABLE_RBU

    启用实现 RBU 扩展 的代码。

    SQLITE_ENABLE_RTREE

    此选项会导致 SQLite 包含对 R*Tree 索引扩展 的支持。

    SQLITE_ENABLE_SESSION

    此选项启用 session 扩展

    SQLITE_ENABLE_SNAPSHOT

    此选项启用代码以支持 sqlite3_snapshot 对象及其相关接口