]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reserve some space at the start of the log-summary file to apply locks to.
authordan <dan@noemail.net>
Sat, 24 Apr 2010 04:49:15 +0000 (04:49 +0000)
committerdan <dan@noemail.net>
Sat, 24 Apr 2010 04:49:15 +0000 (04:49 +0000)
FossilOrigin-Name: a031aa1fa01f062b087154833738f011f7bc4eb5

manifest
manifest.uuid
src/log.c

index 2f6f6317d8c4f27691d699da6f3737639b6c2d7d..ffb0444ea2456ae490c922a98b746015bf4c229e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fixes\sand\stests\sfor\sbackup\sof\sa\sWAL\sdatabase.
-D 2010-04-23T19:15:00
+C Reserve\ssome\sspace\sat\sthe\sstart\sof\sthe\slog-summary\sfile\sto\sapply\slocks\sto.
+D 2010-04-24T04:49:15
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -131,7 +131,7 @@ F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c
 F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
 F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
 F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581
-F src/log.c d9fdaad6b0b5ace54153b85f5bfcf1b9d1abac67
+F src/log.c 7569a2f6541c86127914d50e9fd6e65c17111bc6
 F src/log.h bc44b0eec723648c8aa0a05ab78e1b76a4032e02
 F src/main.c 867de6aa444abd97771b2b70472f448d65c1c77e
 F src/malloc.c a08f16d134f0bfab6b20c3cd142ebf3e58235a6a
@@ -808,7 +808,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 1077d8130b8ed5716ad73f78382270909d347963
-R 0d1581e70f8ee05579afbc11de72b135
+P 480d12db4c0ebcc37598f7620d39193875eab15b
+R f27ff96a8474356c5e71b7eed104ff79
 U dan
-Z c6fc40f98d5658443e299ebf167b2a61
+Z 9b426b4ef3d6b692bab78cb4477e0b43
index 4ef5c841105019557d07bd9eaa539933f4002214..43145bd9a20e3f85ca3cd3315ec927e0c86c589b 100644 (file)
@@ -1 +1 @@
-480d12db4c0ebcc37598f7620d39193875eab15b
\ No newline at end of file
+a031aa1fa01f062b087154833738f011f7bc4eb5
\ No newline at end of file
index c1b734f8fe8a70f7d1aedc860f523d62e80ae85b..3837d7e170e6fe75976b3ffbb9d6ec3a38c97b51 100644 (file)
--- a/src/log.c
+++ b/src/log.c
 */
 
 /* 
-** LOG SUMMARY FORMAT
+** LOG SUMMARY FILE FORMAT
 **
-** TODO.
+** The log-summary file consists of a header region, followed by an 
+** region that contains no useful data (used to apply byte-range locks
+** to), followed by the data region. 
+**
+** The contents of both the header and data region are specified in terms
+** of 1, 2 and 4 byte unsigned integers. All integers are stored in 
+** machine-endian order.
+**
+** A log-summary file is essentially a shadow-pager map. It contains a
+** mapping from database page number to the set of locations in the log 
+** file that contain versions of the database page. When a database 
+** client needs to read a page of data, it first queries the log-summary
+** file to determine if the required version of the page is stored in
+** the log. If so, it is read from the log file. If not, it is read from
+** the database file.
+**
+** Whenever a transaction is appended to the log or a checkpoint transfers
+** data from the log file into the database file, the log-summary is 
+** updated accordingly.
+**
+** The fields in the log-summary file header are described in the comment 
+** directly above the definition of struct LogSummaryHdr (see below). 
+** Immediately following the fields in the LogSummaryHdr structure is
+** an 8 byte checksum based on the contents of the header. This field is
+** not the same as the iCheck1 and iCheck2 fields of the LogSummaryHdr.
 */
 
 #include "log.h"
@@ -65,14 +89,19 @@ struct LogSummaryHdr {
 /* Size of serialized LogSummaryHdr object. */
 #define LOGSUMMARY_HDR_NFIELD (sizeof(LogSummaryHdr) / sizeof(u32))
 
-#define LOGSUMMARY_FRAME_OFFSET \
-  (LOGSUMMARY_HDR_NFIELD + LOG_CKSM_BYTES/sizeof(u32))
-
-
+/* A block of 16 bytes beginning at LOGSUMMARY_LOCK_OFFSET is reserved
+** for locks. Since some systems only feature mandatory file-locks, we
+** do not read or write data from the region of the file on which locks
+** are applied.
+*/
+#define LOGSUMMARY_LOCK_OFFSET   ((sizeof(LogSummaryHdr))+2*sizeof(u32))
+#define LOGSUMMARY_LOCK_RESERVED 16
 
-/* Size of frame header */
+/* Size of header before each frame in log file */
 #define LOG_FRAME_HDRSIZE 16
-#define LOG_HDRSIZE       12
+
+/* Size of log header */
+#define LOG_HDRSIZE 12
 
 /*
 ** Return the offset of frame iFrame in the log file, assuming a database
@@ -80,7 +109,7 @@ struct LogSummaryHdr {
 ** log frame-header.
 */
 #define logFrameOffset(iFrame, pgsz) (                               \
-  LOG_HDRSIZE + ((iFrame)-1)*((pgsz)+LOG_FRAME_HDRSIZE)              \
+  LOG_HDRSIZE + ((iFrame)-1)*((pgsz)+LOG_FRAME_HDRSIZE)        \
 )
 
 /*
@@ -197,9 +226,9 @@ struct LogSummary {
 **         write to the log file) require an exclusive lock on region D.
 **         Which they cannot get until all region D readers have finished.
 */
-#define LOG_LOCK_MUTEX  12
-#define LOG_LOCK_DMH    13
-#define LOG_LOCK_REGION 14
+#define LOG_LOCK_MUTEX  (LOGSUMMARY_LOCK_OFFSET)
+#define LOG_LOCK_DMH    (LOG_LOCK_MUTEX+1)
+#define LOG_LOCK_REGION (LOG_LOCK_DMH+1)
 
 /*
 ** The four lockable regions associated with each log-summary. A connection
@@ -386,13 +415,13 @@ static int logSummaryUnmap(LogSummary *pSummary, int isUnlink){
 }
 
 static void logSummaryWriteHdr(LogSummary *pSummary, LogSummaryHdr *pHdr){
-  u32 *aData = pSummary->aData;
-  memcpy(aData, pHdr, sizeof(LogSummaryHdr));
-  aData[LOGSUMMARY_HDR_NFIELD] = 1;
-  aData[LOGSUMMARY_HDR_NFIELD+1] = 1;
-  logChecksumBytes(
-    (u8 *)aData, sizeof(LogSummaryHdr), &aData[LOGSUMMARY_HDR_NFIELD]
-  );
+  u32 *aHdr = pSummary->aData;                   /* Write header here */
+  u32 *aCksum = &aHdr[LOGSUMMARY_HDR_NFIELD];    /* Write header cksum here */
+
+  assert( LOGSUMMARY_HDR_NFIELD==sizeof(LogSummaryHdr)/4 );
+  memcpy(aHdr, pHdr, sizeof(LogSummaryHdr));
+  aCksum[0] = aCksum[1] = 1;
+  logChecksumBytes((u8 *)aHdr, sizeof(LogSummaryHdr), aCksum);
 }
 
 /*
@@ -553,7 +582,11 @@ static int logSummaryMap(LogSummary *pSummary, int nByte){
 ** alternating "map" and "index" blocks.
 */
 static int logSummaryEntry(u32 iFrame){
-  return ((((iFrame-1)>>8)<<6) + iFrame-1 + 2 + LOGSUMMARY_HDR_NFIELD);
+  return (
+      (LOGSUMMARY_LOCK_OFFSET+LOGSUMMARY_LOCK_RESERVED)/sizeof(u32)
+    + (((iFrame-1)>>8)<<6)        /* Indexes that occur before iFrame */
+    + iFrame-1                    /* Db page numbers that occur before iFrame */
+  );
 }
 
 
@@ -692,6 +725,9 @@ finished:
 /*
 ** Place, modify or remove a lock on the log-summary file associated 
 ** with pSummary.
+**
+** The locked byte-range should be inside the region dedicated to 
+** locking. This region of the log-summary file is never read or written.
 */
 static int logLockFd(
   LogSummary *pSummary,           /* The log-summary object to lock */
@@ -716,6 +752,13 @@ static int logLockFd(
 
   assert( ArraySize(aType)==ArraySize(aOp) );
   assert( op>=0 && op<ArraySize(aType) );
+  assert( nByte>0 );
+  assert( iStart>=LOGSUMMARY_LOCK_OFFSET 
+       && iStart+nByte<=LOGSUMMARY_LOCK_OFFSET+LOGSUMMARY_LOCK_RESERVED
+  );
+#if defined(SQLITE_DEBUG) && defined(SQLITE_OS_UNIX)
+  if( pSummary->aData ) memset(&((u8*)pSummary->aData)[iStart], op, nByte);
+#endif
 
   memset(&f, 0, sizeof(f));
   f.l_type = aType[op];
@@ -834,13 +877,13 @@ static int logLockRegion(Log *pLog, u32 mRegion, int op){
       int iStart;                 /* Byte offset to start locking operation */
       int iLen;                   /* Length field for locking operation */
     } aMap[] = {
-      /* 0000 */ {0, 0},                    /* 0001 */ {4+LOG_LOCK_REGION, 1}, 
-      /* 0010 */ {3+LOG_LOCK_REGION, 1},    /* 0011 */ {3+LOG_LOCK_REGION, 2},
-      /* 0100 */ {2+LOG_LOCK_REGION, 1},    /* 0101 */ {0, 0}, 
-      /* 0110 */ {2+LOG_LOCK_REGION, 2},    /* 0111 */ {2+LOG_LOCK_REGION, 3},
-      /* 1000 */ {1+LOG_LOCK_REGION, 1},    /* 1001 */ {0, 0}, 
+      /* 0000 */ {0, 0},                    /* 0001 */ {3+LOG_LOCK_REGION, 1}, 
+      /* 0010 */ {2+LOG_LOCK_REGION, 1},    /* 0011 */ {2+LOG_LOCK_REGION, 2},
+      /* 0100 */ {1+LOG_LOCK_REGION, 1},    /* 0101 */ {0, 0}, 
+      /* 0110 */ {1+LOG_LOCK_REGION, 2},    /* 0111 */ {1+LOG_LOCK_REGION, 3},
+      /* 1000 */ {0+LOG_LOCK_REGION, 1},    /* 1001 */ {0, 0}, 
       /* 1010 */ {0, 0},                    /* 1011 */ {0, 0},
-      /* 1100 */ {1+LOG_LOCK_REGION, 2},    /* 1101 */ {0, 0}, 
+      /* 1100 */ {0+LOG_LOCK_REGION, 2},    /* 1101 */ {0, 0}, 
       /* 1110 */ {0, 0},                    /* 1111 */ {0, 0}
     };
     int rc;                       /* Return code of logLockFd() */