可以将SQLite配置为在发生异常时调用包含错误代码和简短错误消息的回调函数。该机制对于跟踪在现场很少发生的模糊问题非常有用。鼓励应用程序开发人员在他们的产品中利用SQLite的错误日志记录功能,因为它的CPU和内存成本非常低,但可以极大地帮助调试。
每个进程只能有一个错误日志记录回调。错误日志回调在启动时使用类似于以下内容的C代码进行注册:
sqlite3_config(SQLITE_CONFIG_LOG,errorLogCallback,pData);
错误记录器回调函数可能看起来像这样:
void errorLogCallback(void * pArg,int iErrCode,const char * zMsg){ fprintf(stderr,“(%d)%s \ n”,iErrCode,zMsg); }
上面的示例说明了错误记录器回调的签名。但是,在嵌入式应用程序中,通常不会在stderr上打印消息。取而代之的是,可以将消息存储在预分配的循环缓冲区中,在调试期间需要诊断信息时可以在其中访问这些消息。或者,消息可以发送到Syslog。消息必须以某种方式存储在开发人员可以访问的位置,而不显示给最终用户。
不要误会:向最终用户显示错误记录器消息在技术上没有任何错误。消息不包含敏感信息或私人信息,必须加以保护以防止未经授权的查看。而是这些消息本质上是技术性的,对典型的最终用户没有用或没有意义。来自错误记录器的消息适用于数据库极客。相应地显示它们。
sqlite3_config(SQLITE_CONFIG_LOG,...)接口的第三个参数(上面示例中的“ pData”参数)是指向任意数据的指针。SQLite将此指针传递到错误记录器回调的第一个参数。如果需要,可以使用该指针传递特定于应用程序的设置或状态信息。或者它可以只是一个NULL指针,该指针将被回调忽略。
错误记录器回调的第二个参数是整数 扩展错误代码。错误记录器的第三个参数是错误消息的文本。错误消息文本存储在调用函数的固定长度堆栈缓冲区中,因此仅在错误记录器回调函数期间有效。如果需要保留消息,则错误记录器应将此消息复制到持久性存储中。
错误记录器回调应被视为信号处理程序。应用程序应保存或以其他方式处理该错误,然后尽快返回。不应从错误记录器直接或间接调用其他SQLite API。通过错误记录器回调,SQLite不可重入。特别是,当内存分配失败时,将调用错误记录器回调,因此尝试在错误记录器中分配内存通常是一个坏主意。甚至不要考虑尝试将错误消息存储在另一个SQLite数据库中。
如果需要,应用程序可以使用sqlite3_log(E,F,..) API将新消息发送到日志,但是不建议这样做。所述sqlite3_log() 接口只,而不是由应用程序打算由扩展。
可能会发送到错误记录器的错误消息及其确切格式可能会从一个版本更改为另一个版本。因此,应用程序不应依赖于任何特定的错误消息文本格式或错误代码。事情不会反复无常,但有时会发生变化。
以下是错误记录器回调中可能出现的各种消息的部分列表。
每当编译SQL语句(使用sqlite3_prepare_v2()或其同级)或运行SQL语句(使用sqlite3_step())时发生错误时,都会记录该错误。
当发生架构更改,需要重新准备和重新准备一条准备好的语句时,该事件将记录为错误代码SQLITE_SCHEMA。reparse和reprepare通常是自动的(假设 已使用sqlite3_prepare_v2()最初准备了语句,建议这样做),因此这些日志记录事件通常是知道正在进行重新准备的唯一方法。
每当必须恢复数据库时,都会记录SQLITE_NOTICE消息,因为前一个编写器在未完成其事务的情况下崩溃了。恢复回滚日志时,错误代码为SQLITE_NOTICE_RECOVER_ROLLBACK,而恢复预 写日志时,错误代码为SQLITE_NOTICE_RECOVER_WAL 。
当数据库文件以可能导致数据库损坏的方式重命名或别名时,会记录SQLITE_WARNING消息。(有关更多信息,请参见1和2。)
内存不足(OOM)错误情况会生成带有SQLITE_NOMEM错误代码和一条消息的错误日志记录事件,该消息指出失败的分配请求了多少字节的内存。
OS接口中的I / O错误会生成错误记录事件。这些事件的消息给出了源代码中错误发生的行号,以及在存在相应文件时与事件关联的文件名。
当检测到数据库损坏时,将调用SQLITE_CORRUPT错误记录器回调。与I / O错误一样,错误消息文本包含原始源代码中首次检测到错误的行号。
对SQLITE_MISUSE错误调用错误记录器回调。当未在应用程序代码中一致地检查返回代码时,这对于检测应用程序设计问题很有用。
SQLite努力将错误记录器的流量保持在较低水平,并且仅在确实存在问题时才将消息发送到错误记录器。应用程序可能会故意忽略它们不关心的某些类别的错误消息,从而进一步消除错误消息的流量。例如,经常更改数据库架构的应用程序可能要忽略所有SQLITE_SCHEMA错误。
强烈建议使用错误记录器回调。事实证明,错误记录器提供的调试信息对于跟踪应用程序进入现场后出现的晦涩问题非常有用。事实证明,错误记录器回调可用于捕获由于API返回码检查不一致而导致应用程序遗漏的偶然错误。鼓励开发人员在开发周期的早期实施错误记录器回调,以便快速发现意外行为,并在部署过程中保持打开错误记录器回调的状态。如果错误记录器从未发现问题,则不会造成任何危害。但是,未能设置适当的错误记录器可能会在以后损害诊断功能。