在断电期间,SQLite 将我的数据库回滚到 BEGIN 之前的某个点
During power loss, SQLite rollbacks my DB to a point before BEGIN
我的应用程序中有一个 SQLite 数据库。每次应用 modifies/adds 数据库中的一行时,应用都会通过发出命令 BEING TRANSACTION
显式启动 SQLite 事务。在我的数据库中 updating/adding 数据之后,我发出命令 COMMIT
,如果更新失败则发出 ROLLBACK
。平常的东西(https://www.sqlite.org/lang_transaction.html)。一切正常,直到我断电。
问题是每次我在应用程序执行 COMMIT
、启动设备并最终启动应用程序后断电,SQLITE 保留数据,就好像 BEGIN
和 [=11= 】 根本就没有发生过!为什么?
我也检查了我的应用程序目录中的数据库文件,它有正确的数据。我还注意到我的应用程序目录中有一个额外的文件 <mydatabasefilename>-journal
。经查,这是SQLite用来支持回滚未完成事务的temp file,尤其是在断电时。
同样,我的 COMMIT
发生在停电之前。我的数据库文件(在我的应用程序目录中检查过)包含正确的数据。但为什么 <mydatabasefilename>-journal
包含较旧的数据?我完全不明白。我在这里遗漏了什么吗?
您的数据库使用什么 PRAGMA synchronous
和 PRAGMA journal_mode
设置?这些可用于控制 sqlite 在这些方面的确切行为。
包含旧内容的 <mydatabasefilename>-journal
文件的行为听起来像此处描述的回滚日志:https://www.sqlite.org/lockingv3.html#rollback
When a process wants to change a database file (and it is not in WAL mode), it first records the original unchanged database content in a rollback journal. The rollback journal is an ordinary disk file that is always located in the same directory or folder as the database file and has the same name as the database file with the addition of a -journal suffix. [...]
[...]
A rollback journal is said to be hot if it needs to be rolled back in order to restore the integrity of its database. A hot journal is created when a process is in the middle of a database update and a program or operating system crash or power failure prevents the update from completing. Hot journals are an exception condition. Hot journals exist to recover from crashes and power failures. If everything is working correctly (that is, if there are no crashes or power failures) you will never get a hot journal.
此处描述了可以设置的不同日志模式:https://www.sqlite.org/pragma.html#pragma_journal_mode
The DELETE journaling mode is the normal behavior. In the DELETE mode, the rollback journal is deleted at the conclusion of each transaction. Indeed, the delete operation is the action that causes the transaction to commit. (See the document titled Atomic Commit In SQLite for additional detail.)
您可以尝试为 PRAGMA synchronous
设置其他设置,请参阅这些设置:https://www.sqlite.org/pragma.html#pragma_synchronous
- EXTRA (3)
EXTRA synchronous is like FULL with the addition that the directory containing a rollback journal is synced after that journal is unlinked to commit a transaction in DELETE mode. EXTRA provides additional durability if the commit is followed closely by a power loss.
- 已满 (2)
When synchronous is FULL (2), the SQLite database engine will use the xSync method of the VFS to ensure that all content is safely written to the disk surface prior to continuing. This ensures that an operating system crash or power failure will not corrupt the database. FULL synchronous is very safe, but it is also slower. FULL is the most commonly used synchronous setting when not in WAL mode.
所以在你的情况下,设置 PRAGMA synchronous = EXTRA;
可能会达到你想要的效果,但这可能会以性能成本为代价。
您也可以尝试使用 PRAGMA journal_mode = WAL;
进行试验,如 https://www.sqlite.org/wal.html 所述,如果 PRAGMA synchronous
.[=25 的设置较轻,那么它在断电时更适合您=]
我的应用程序中有一个 SQLite 数据库。每次应用 modifies/adds 数据库中的一行时,应用都会通过发出命令 BEING TRANSACTION
显式启动 SQLite 事务。在我的数据库中 updating/adding 数据之后,我发出命令 COMMIT
,如果更新失败则发出 ROLLBACK
。平常的东西(https://www.sqlite.org/lang_transaction.html)。一切正常,直到我断电。
问题是每次我在应用程序执行 COMMIT
、启动设备并最终启动应用程序后断电,SQLITE 保留数据,就好像 BEGIN
和 [=11= 】 根本就没有发生过!为什么?
我也检查了我的应用程序目录中的数据库文件,它有正确的数据。我还注意到我的应用程序目录中有一个额外的文件 <mydatabasefilename>-journal
。经查,这是SQLite用来支持回滚未完成事务的temp file,尤其是在断电时。
同样,我的 COMMIT
发生在停电之前。我的数据库文件(在我的应用程序目录中检查过)包含正确的数据。但为什么 <mydatabasefilename>-journal
包含较旧的数据?我完全不明白。我在这里遗漏了什么吗?
您的数据库使用什么 PRAGMA synchronous
和 PRAGMA journal_mode
设置?这些可用于控制 sqlite 在这些方面的确切行为。
包含旧内容的 <mydatabasefilename>-journal
文件的行为听起来像此处描述的回滚日志:https://www.sqlite.org/lockingv3.html#rollback
When a process wants to change a database file (and it is not in WAL mode), it first records the original unchanged database content in a rollback journal. The rollback journal is an ordinary disk file that is always located in the same directory or folder as the database file and has the same name as the database file with the addition of a -journal suffix. [...]
[...]
A rollback journal is said to be hot if it needs to be rolled back in order to restore the integrity of its database. A hot journal is created when a process is in the middle of a database update and a program or operating system crash or power failure prevents the update from completing. Hot journals are an exception condition. Hot journals exist to recover from crashes and power failures. If everything is working correctly (that is, if there are no crashes or power failures) you will never get a hot journal.
此处描述了可以设置的不同日志模式:https://www.sqlite.org/pragma.html#pragma_journal_mode
The DELETE journaling mode is the normal behavior. In the DELETE mode, the rollback journal is deleted at the conclusion of each transaction. Indeed, the delete operation is the action that causes the transaction to commit. (See the document titled Atomic Commit In SQLite for additional detail.)
您可以尝试为 PRAGMA synchronous
设置其他设置,请参阅这些设置:https://www.sqlite.org/pragma.html#pragma_synchronous
- EXTRA (3)
EXTRA synchronous is like FULL with the addition that the directory containing a rollback journal is synced after that journal is unlinked to commit a transaction in DELETE mode. EXTRA provides additional durability if the commit is followed closely by a power loss.
- 已满 (2)
When synchronous is FULL (2), the SQLite database engine will use the xSync method of the VFS to ensure that all content is safely written to the disk surface prior to continuing. This ensures that an operating system crash or power failure will not corrupt the database. FULL synchronous is very safe, but it is also slower. FULL is the most commonly used synchronous setting when not in WAL mode.
所以在你的情况下,设置 PRAGMA synchronous = EXTRA;
可能会达到你想要的效果,但这可能会以性能成本为代价。
您也可以尝试使用 PRAGMA journal_mode = WAL;
进行试验,如 https://www.sqlite.org/wal.html 所述,如果 PRAGMA synchronous
.[=25 的设置较轻,那么它在断电时更适合您=]