]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the showtmlog utility for decoding the tmstmpvfs log files.
authordrh <>
Thu, 8 Jan 2026 12:22:50 +0000 (12:22 +0000)
committerdrh <>
Thu, 8 Jan 2026 12:22:50 +0000 (12:22 +0000)
Fix tmstmpvfs so that it records timestamps in milliseconds since the
Unix epoch, not in JDN milliseconds.

FossilOrigin-Name: 762d3cbf06218f1010425a98a71ebf7623b84b45a90e6419b7dec7f10ad0c5a5

Makefile.msc
ext/misc/tmstmpvfs.c
main.mk
manifest
manifest.uuid
tool/showtmlog.c [new file with mode: 0644]

index 219f5c4f9dbedbd7d25dcf2d1f0cef7eb7c9e0e3..561d5f58e0f675f400a1203030e0dc1e3d4a6d1e 100644 (file)
@@ -2709,6 +2709,9 @@ showwal.exe:      $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
 showshm.exe:   $(TOP)\tool\showshm.c
        $(LTLINK) $(NO_WARN)    $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS)
 
+showtmlog.exe: $(TOP)\tool\showtmlog.c
+       $(LTLINK) $(NO_WARN)    $(TOP)\tool\showtmlog.c /link $(LDFLAGS) $(LTLINKOPTS)
+
 index_usage.exe: $(TOP)\tool\index_usage.c $(SQLITE3C) $(SQLITE3H)
        $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
                $(TOP)\tool\index_usage.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
index 888b6cf5e12c0ec8d65e75020e2d2f6a7dbdd645..94630cc4ef52c8a51572855ac67979a3b8dda320 100644 (file)
 **     op  a1  ts   a2  a3
 **
 ** The meanings of the a1-a3 values depend on op.  ts is the timestamp
-** in milliseconds since 1970-01-01.  (6 bytes is sufficient for timestamps
-** for almost 9000 years.) Opcodes are defined by the ELOG_* #defines
-** below.
+** in milliseconds since the unix epoch (1970-01-01 00:00:00).
+** Opcodes are defined by the ELOG_* #defines below.
 **
 **   ELOG_OPEN_DB         "Open a connection to the database file"
 **                        op = 0x01
@@ -377,6 +376,7 @@ static const sqlite3_io_methods tmstmp_io_methods = {
 static void tmstmpPutTS(TmstmpFile *p, unsigned char *aOut){
   sqlite3_uint64 tm = 0;
   p->pSubVfs->xCurrentTimeInt64(p->pSubVfs, (sqlite3_int64*)&tm);
+  tm -= 210866760000000LL;
   aOut[0] = (tm>>40)&0xff;
   aOut[1] = (tm>>32)&0xff;
   aOut[2] = (tm>>24)&0xff;
@@ -775,6 +775,7 @@ static int tmstmpOpen(
     memset(pLog, 0, sizeof(pLog[0]));
     p->pLog = pLog;
     p->pSubVfs->xCurrentTimeInt64(p->pSubVfs, (sqlite3_int64*)&r1);
+    r1 -= 210866760000000LL;
     sqlite3_randomness(sizeof(r2), &r2);
     pid = GETPID;
     pLog->zLogname = sqlite3_mprintf("%s-tmstmp/%llx-%08x-%08x",
diff --git a/main.mk b/main.mk
index 91fcc1b9464f755870c238d05293d6dd5eac79ec..8b5d2821cf77a9a43b3f8b3d7e3a8861497c7413 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -2018,6 +2018,10 @@ showshm$(T.exe): $(TOP)/tool/showshm.c
        $(T.link) -o $@ $(TOP)/tool/showshm.c $(LDFLAGS.configure)
 xbin: showshm$(T.exe)
 
+showtmlog$(T.exe):     $(TOP)/tool/showtmlog.c
+       $(T.link) -o $@ $(TOP)/tool/showtmlog.c $(LDFLAGS.configure)
+xbin: showshm$(T.exe)
+
 index_usage$(T.exe): $(TOP)/tool/index_usage.c sqlite3.o
        $(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o \
                $(LDFLAGS.libsqlite3)
index 543e9c293d49d2029178a7f2d4435346021b96d7..10842b5320d819d8400e4aed9bc53766fa7d550b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,12 +1,12 @@
-C Improve\sshowdb\sso\sthat\sit\sdoes\sa\sbetter\sjob\sof\shandling\sreserve-bytes.\nAdd\sthe\s--tmstmp\soption\sthat\scauses\spgidx\sto\sinterpret\stmstmpvfs\stags\nif\sthey\sare\savailable.
-D 2026-01-08T01:37:13.895
+C Add\sthe\sshowtmlog\sutility\sfor\sdecoding\sthe\stmstmpvfs\slog\sfiles.\nFix\stmstmpvfs\sso\sthat\sit\srecords\stimestamps\sin\smilliseconds\ssince\sthe\nUnix\sepoch,\snot\sin\sJDN\smilliseconds.
+D 2026-01-08T12:22:50.349
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
 F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
-F Makefile.msc 48c5be34727fd835c675eb9a6ba21900d66088fcec81210cb2e134927aa0fa4f
+F Makefile.msc 1fa179beafd6d438b8479146cae77fb1724dd35b330b09dbfebd8a2f0823c62a
 F README.md 3fa51fc7ababc32edd175ae8b2986c86d5ea120c1cb1e57c7f7849492d1405ec
 F VERSION 74672bfd4c7826c0fc6f84762488a707c52e7d2d94af42ccb0edcc6c74311c41
 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
@@ -402,7 +402,7 @@ F ext/misc/sqlite3_stdio.h 27a4ecea47e61bc9574ccdf2806f468afe23af2f95028c9b689bf
 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321
 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc
 F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b
-F ext/misc/tmstmpvfs.c 4953aa97872c67d55e22351cdf3dc3d06e81ef0f28c6105f1fae2214f3250c74
+F ext/misc/tmstmpvfs.c f7845d1641cfc26d78ae017ccabc05cb01f712db07f95ae1bad1df564d566a2a
 F ext/misc/totype.c ba11aac3c0b52c685bd25aa4e0f80c41c624fb1cc5ab763250e09ddc762bc3a8
 F ext/misc/uint.c 327afc166058acf566f33a15bf47c869d2d3564612644d9ff81a23efc8b36039
 F ext/misc/unionvtab.c 716d385256d5fb4beea31b0efede640807e423e85c9784d21d22f0cce010a785
@@ -659,7 +659,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
 F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
-F main.mk ba9ac943f81c80cd2d7b502759e60d23a988be74cc7b4b1575419932fe2afcb0
+F main.mk 9393d5982db60f26e72c5af24a8c11cf39374ff5e695fadb5a4e7376f28150c6
 F make.bat a136fd0b1c93e89854a86d5f4edcf0386d211e5d5ec2434480f6eea436c7420c
 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -2164,6 +2164,7 @@ F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
 F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564
 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809
 F tool/showstat4.c b706fcbc4cd1a6e4a73ac32549afc4b460479d650402d64b23e8d813516e8de4
+F tool/showtmlog.c 5e5d8b217ce48056583f97c7c16d68287bbaeff77ef6d4b54cbc2c7ca298a44f
 F tool/showwal.c 11eca547980a066b081f512636151233350ac679f29ecf4ebfce7f4530230b3d
 F tool/soak1.tcl a3892082ed1079671565c044e93b55c3c7f38829aedf53cc597c65d23ffdaddf
 F tool/spaceanal.tcl 1f83962090a6b60e1d7bf92495d643e622bef9fe82ea3f2d22350dcbce9a12d0
@@ -2190,8 +2191,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 869f306592a86d2a78f00266c615f033cd2318a7bff0a97b3dcdd3348d99fc66
-R 84dfc7b9c377c2c122ebbcbfef876fb5
+P d7e6e9a5781f467a5b5f02f46134099cf01607a0cf55510155533d57d4a4618a
+R 480580b84284dc2078a6aa5caacd15c8
 U drh
-Z da6fd7cd7ce3a4452ba602eb99ca3b3b
+Z 20a5cec87f22c6e120bc0b5fcbbfb23d
 # Remove this line to create a well-formed Fossil manifest.
index ae055627fe85ed2440da678f96a81fa05dfa4427..63a01af7aad57ba230fda1a5f0d64741c4e31964 100644 (file)
@@ -1 +1 @@
-d7e6e9a5781f467a5b5f02f46134099cf01607a0cf55510155533d57d4a4618a
+762d3cbf06218f1010425a98a71ebf7623b84b45a90e6419b7dec7f10ad0c5a5
diff --git a/tool/showtmlog.c b/tool/showtmlog.c
new file mode 100644 (file)
index 0000000..d3da92f
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+** A utility program to decode tmstmpvfs log files.
+*/
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+
+/*
+** The six bytes at a[] are a big-endian unsigned integer which is the
+** number of milliseconds since 1970.  Decode that value into an ISO 8601
+** date/time string stored in static space and return a pointer to that
+** string.
+*/
+static const char *decodeTimestamp(const unsigned char *a){
+  uint64_t ms;               /* Milliseconds since 1970 */
+  uint64_t days;             /* Days since 1970-01-01 */
+  uint64_t sod;              /* Start of date specified by ms */
+  uint64_t z;                /* Days since 0000-03-01 */
+  uint64_t era;              /* 400-year era */
+  int i;                     /* Loop counter */
+  int h;                     /* hour */
+  int m;                     /* minute */
+  int s;                     /* second */
+  int f;                     /* millisecond */
+  int Y;                     /* year */
+  int M;                     /* month */
+  int D;                     /* day */
+  int y;                     /* year assuming March is first month */
+  unsigned int doe;          /* day of 400-year era */
+  unsigned int yoe;          /* year of 400-year era */
+  unsigned int doy;          /* day of year */
+  unsigned int mp;           /* month with March==0 */
+  static char zOut[50];      /* Return results here */
+
+  for(ms=0, i=0; i<=5; i++) ms = (ms<<8) + a[i];
+  if( ms>253402300800000LL ){
+        /*  YYYY-MM-DD HH:MM:SS.SSS */
+    return "---date out of range---";
+  }
+  days = ms/86400000;
+  sod = (ms%86400000)/1000;
+  f = (int)(ms%1000);
+
+  h = sod/3600;
+  m = (sod%3600)/60;
+  s = sod%60;
+  z = days + 719468;
+  era = z/147097;
+  doe = (unsigned)(z - era*146097);
+  yoe = (doe - doe/1460 + doe/36524 - doe/146096)/365;
+  y = (int)yoe + era*400;
+  doy = doe - (365*yoe + yoe/4 - yoe/100);
+  mp = (5*doy + 2)/153;
+  D = doy - (153*mp + 2)/5 + 1;
+  M = mp + (mp<10 ? 3 : -9);
+  Y = y + (M <=2);
+  snprintf(zOut, sizeof(zOut),
+         "%04d-%02d-%02d %02d:%02d:%02d.%03d",
+             Y,   M,   D,   h,   m,   s,   f);
+  return zOut;
+}
+
+int main(int argc, char **argv){
+  int i;
+  FILE *in;
+  unsigned int a2, a3;
+  unsigned char a[16];
+  for(i=1; i<argc; i++){
+    in = fopen(argv[i], "rb");
+    if( in==0 ){
+      printf("%s: can't open\n", argv[i]);
+      continue;
+    }
+    if( argc>2 ){
+      printf("*** %s ***\n", argv[i]);
+    }
+    while( 16==fread(a, 1, 16, in) ){
+      printf("%s ", decodeTimestamp(a+2));
+      for(a2=0, i=8; i<=11; i++) a2 = (a2<<8)+a[i];
+      for(a3=0, i=12; i<=15; i++) a3 = (a3<<8)+a[i];
+      switch( a[0] ){
+        case 0x01: {
+          printf("open-db   pid %u\n", a2);
+          break;
+        }
+        case 0x02: {
+          printf("open-wal  pid %u\n", a2);
+          break;
+        }
+        case 0x03: {
+          printf("wal-page  pgno %-8u frame %-8u%s\n", a2, a3,
+                 a[1]==1 ? " txn" : "");
+          break;
+        }
+        case 0x04: {
+          printf("db-page   pgno %-8u\n", a2);
+          break;
+        }
+        case 0x05: {
+          printf("ckpt-start\n");
+          break;
+        }
+        case 0x06: {
+          printf("ckpt-page pgno %-8u\n", a2);
+          break;
+        }
+        case 0x07: {
+          printf("ckpt-end\n");
+          break;
+        }
+        case 0x08: {
+          printf("wal-reset salt1 0x%08x\n", a3);
+          break;
+        }
+        case 0x0e: {
+          printf("close-wal\n");
+          break;
+        }
+        case 0x0f: {
+          printf("close-db\n");
+          break;
+        }
+        default: {
+          printf("invalid-record\n");
+          break;
+        }
+      }
+    }
+    fclose(in);
+  }
+  return 0;
+}