Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for race condition in WAL locking code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | mistake |
Files: | files | file ages | folders |
SHA1: |
7c102c7b5f90717f55d95e3d38f33684 |
User & Date: | dan 2010-06-09 11:02:13.000 |
References
2010-06-09
| ||
11:28 | Simpler fix for the race condition also fixed by [7c102c7b5f] (check-in: 3c2de82003 user: dan tags: trunk) | |
Context
2010-06-09
| ||
11:02 | Fix for race condition in WAL locking code. (Closed-Leaf check-in: 7c102c7b5f user: dan tags: mistake) | |
2010-06-08
| ||
15:50 | Close database opened by tester.tcl when it is sourced in all.test. Because test scripts are now run in slave interpreters, this connection was not being closed by the first script run as it was previously. (check-in: b072e9f69a user: dan tags: trunk) | |
Changes
Changes to src/wal.c.
︙ | ︙ | |||
1788 1789 1790 1791 1792 1793 1794 | if( mxI==0 ){ /* If we get here, it means that all of the aReadMark[] entries between ** 1 and WAL_NREADER-1 are zero. Try to initialize aReadMark[1] to ** be mxFrame, then retry. */ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), 1); if( rc==SQLITE_OK ){ | > > | > | > > | | > | 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 | if( mxI==0 ){ /* If we get here, it means that all of the aReadMark[] entries between ** 1 and WAL_NREADER-1 are zero. Try to initialize aReadMark[1] to ** be mxFrame, then retry. */ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), 1); if( rc==SQLITE_OK ){ sqlite3OsShmBarrier(pWal->pDbFd); if( 0==memcmp((void *)pHdr, &pWal->hdr, sizeof(WalIndexHdr)) ){ pInfo->aReadMark[1] = pWal->hdr.mxFrame+1; } walUnlockExclusive(pWal, WAL_READ_LOCK(1), 1); rc = WAL_RETRY; }else if( rc==SQLITE_BUSY ){ rc = WAL_RETRY; } return rc; }else{ if( mxReadMark<=pWal->hdr.mxFrame ){ for(i=1; i<WAL_NREADER; i++){ rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ sqlite3OsShmBarrier(pWal->pDbFd); if( 0==memcmp((void *)pHdr, &pWal->hdr, sizeof(WalIndexHdr)) ){ mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame+1; mxI = i; } walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; }else if( rc!=SQLITE_BUSY ){ return rc; } } } |
︙ | ︙ | |||
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 | sqlite3OsShmBarrier(pWal->pDbFd); if( pInfo->aReadMark[mxI]!=mxReadMark || memcmp((void *)pHdr, &pWal->hdr, sizeof(WalIndexHdr)) ){ walUnlockShared(pWal, WAL_READ_LOCK(mxI)); return WAL_RETRY; }else{ pWal->readLock = mxI; } } return rc; } /* | > | 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 | sqlite3OsShmBarrier(pWal->pDbFd); if( pInfo->aReadMark[mxI]!=mxReadMark || memcmp((void *)pHdr, &pWal->hdr, sizeof(WalIndexHdr)) ){ walUnlockShared(pWal, WAL_READ_LOCK(mxI)); return WAL_RETRY; }else{ assert( mxReadMark<=(pWal->hdr.mxFrame+1) ); pWal->readLock = mxI; } } return rc; } /* |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | set ints [set_tvfs_hdr $file] set v [lindex $ints $idx] incr v $incrval lset ints $idx $v set_tvfs_hdr $file $ints } #------------------------------------------------------------------------- # Test case wal2-1.*: # # Set up a small database containing a single table. The database is not # checkpointed during the test - all content resides in the log file. # | > > > > > > > > > > > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | set ints [set_tvfs_hdr $file] set v [lindex $ints $idx] incr v $incrval lset ints $idx $v set_tvfs_hdr $file $ints } proc clear_tvfs_readmarks {file} { set blob [tvfs shm $file] binary scan $blob i21 ints lappend ints 0 0 0 0 0 binary scan $blob a104a* dummy tail set blob [binary format i26a* $ints $tail] tvfs shm $file $blob } #------------------------------------------------------------------------- # Test case wal2-1.*: # # Set up a small database containing a single table. The database is not # checkpointed during the test - all content resides in the log file. # |
︙ | ︙ | |||
163 164 165 166 167 168 169 170 171 172 173 174 175 176 | # After this, the header is corrupted again and the reader is allowed # to run recovery. This time, it sees an up-to-date snapshot of the # database file. # set WRITER [list 0 1 lock exclusive] set LOCKS [list \ {0 1 lock exclusive} {0 1 unlock exclusive} \ {4 1 lock shared} {4 1 unlock shared} \ ] do_test wal2-2.0 { testvfs tvfs tvfs script tvfs_cb proc tvfs_cb {method args} { | > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | # After this, the header is corrupted again and the reader is allowed # to run recovery. This time, it sees an up-to-date snapshot of the # database file. # set WRITER [list 0 1 lock exclusive] set LOCKS [list \ {0 1 lock exclusive} {0 1 unlock exclusive} \ {4 1 lock exclusive} {4 1 unlock exclusive} \ {4 1 lock shared} {4 1 unlock shared} \ ] do_test wal2-2.0 { testvfs tvfs tvfs script tvfs_cb proc tvfs_cb {method args} { |
︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 234 235 236 237 | } } if {$method == "xShmLock"} { set lock [lindex $args 2] lappend ::locks $lock if {$lock == $::WRITER} { set_tvfs_hdr $::shm_file $::oldhdr } } return SQLITE_OK } execsql { SELECT count(a), sum(a) FROM t1 } db2 } $res0 | > | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | } } if {$method == "xShmLock"} { set lock [lindex $args 2] lappend ::locks $lock if {$lock == $::WRITER} { set_tvfs_hdr $::shm_file $::oldhdr clear_tvfs_readmarks $::shm_file } } return SQLITE_OK } execsql { SELECT count(a), sum(a) FROM t1 } db2 } $res0 |
︙ | ︙ | |||
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 | 5 $wih(2) $wih(1) {Barton Deakin Watson} \ 6 $wih(2) $wih(2) {Barton Deakin Watson} \ 7 $wih(1) $wih(1) {Barton Deakin} \ 8 {0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0} {Barton Deakin Watson} \ ] { do_test wal2-9.$tn { set_tvfs_hdr $::filename $hdr1 $hdr2 execsql { SELECT * FROM x } db2 } $res } db2 close db close finish_test | > | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 | 5 $wih(2) $wih(1) {Barton Deakin Watson} \ 6 $wih(2) $wih(2) {Barton Deakin Watson} \ 7 $wih(1) $wih(1) {Barton Deakin} \ 8 {0 0 0 0 0 0 0 0 0 0} {0 0 0 0 0 0 0 0 0 0} {Barton Deakin Watson} \ ] { do_test wal2-9.$tn { set_tvfs_hdr $::filename $hdr1 $hdr2 clear_tvfs_readmarks $::shm_file execsql { SELECT * FROM x } db2 } $res } db2 close db close finish_test |