Sqlite3的synchronous的模式选择
关于Sqlite3的synchronous的模式选择,网上有很多类似的信息如下,中英文似乎都是这么一段: 1.如何设置: PRAGMA synchronous = FULL; (2) PRAGMA synchronous = NORMAL; (1) PRAGMA synchronous = OFF; (0)2.参数含义: 当synchronous设置为FULL (2),SQLite 数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。这使 系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。 当synchronous设置为NORMAL,SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况 下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。 设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL。 但是对于上述的“SQLite 数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘”,阐述的并不是很清楚,其如何实现的也根本没提。 同样查找相关资料,在Sqlite3的官网论坛上也有人问类似的问题: Yes,I have read that,along with all the threads/posts I could find from the Internet. The thing that I cannot fully understand is how can FULL (2) guarantee durability,but NORMAL (1) cannot. Before making an attempt to look into the code,I just wanted to see if anyone can help provide some explanation. Durability means a transaction cannot be lost,and I know FULL (1) will provide that. The question is why NORMAL (1) cannot provide the same. I am using EXT3 with barrier=1 and write-cache disabled from the HDD, as far as I know this is as good as it gets for making the system reliable. So,in this case,will the NORMAL (1) actually cause data loss on power loss? I already know that corruption will not happen,I am just interested in the "losing transactions" or "sacrifice durability" as suggested in various threads/posts I have read. 看看论坛上其他人得回答,似乎还是不是很满意其解释。 看下官网上的说明: PRAGMA database.synchronous; Query or change the setting of the "synchronous" flag. The first (query) form will return the synchronous setting as an integer. 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. When synchronous is NORMAL (1),the SQLite database engine will still sync at the most critical moments,but less often than in FULL mode. There is a very small (though non-zero) chance that a power failure at just the wrong time could corrupt the database in NORMAL mode. But in practice,you are more likely to suffer a catastrophic disk failure or some other unrecoverable hardware fault. With synchronous OFF (0),SQLite continues without syncing as soon as it has handed data off to the operating system. If the application running SQLite crashes,the data will be safe,but the database might become corrupted if the operating system crashes or the computer loses power before that data has been written to the disk surface. On the other hand,some operations are as much as 50 or more times faster with synchronous OFF. In WAL mode when synchronous is NORMAL (1),the WAL file is synchronized before each checkpoint and the database file is synchronized after each completed checkpoint and the WAL file header is synchronized when a WAL file begins to be reused after a checkpoint,but no sync operations occur during most transactions. With synchronous=FULL in WAL mode,an additional sync operation of the WAL file happens after each transaction commit. The extra WAL sync following each transaction help ensure that transactions are durable across a power loss,but they do not aid in preserving consistency. If durability is not a concern,then synchronous=NORMAL is normally all one needs in WAL mode. The default setting is synchronous=FULL. See also the fullfsync and checkpoint_fullfsync pragmas. 网上赞同意见较多的解释, In WAL mode,when a transaction is written to disk,the modified pages are appended to the *-wal file. Later on,during a checkpoint,all the modified pages in the *-wal file are copied back into the database file. In both synchronous=NORMAL and synchronous=FULL the *-wal file may contain more than one transaction. One fsync() per transaction written to the WAL file. 补充的意见是: SQLite3 working correctly depends on the SQLite3 calls writing directly to the disk,with the disk physically part of the computer that's executing the SQLite3 calls. If you're mounting the disk using NFS or any other network FS,the answers are different. Very few network setups correctly support fsync(). 个人理解最关键的地方在于: 数据库为了执行备份,备份文件依赖于写磁盘,然后才会写到数据库文件磁盘中。关键在于这里的写磁盘,都是调用系统的write接口,绝大部分都是直接写缓冲区的,只有调用sync才会将缓冲区中的数据flush到磁盘。所以在write,sync,再wirte再sync的过程中,掉电后是否能恢复数据,依赖于sync是否有真正执行。从这个角度看,FULL和NORMAL的区别,似乎就只有sync调用的频率,FULL按照多人的意见是一个transaction一个sync,而NORMAL是多个transactions调一个sync (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |