/ Check-in [eed701ef91]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:In the "pgidx" command of the showdb utility, try to identify orphaned pages and show when pages have been zeroed out.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d
User & Date: drh 2019-04-17 12:29:45
Context
2019-04-17
13:23
In the "pgidx" report from "showdb", also show the number of rows on each database btree page. check-in: 2bda9dc41c user: drh tags: trunk
12:29
In the "pgidx" command of the showdb utility, try to identify orphaned pages and show when pages have been zeroed out. check-in: eed701ef91 user: drh tags: trunk
12:07
Small performance improvement on the variable-length integer decoder: sqlite3GetVarint(). check-in: 5df2bf62fc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to tool/showdb.c.

831
832
833
834
835
836
837






838


839
840



841
842
843
844
845
846
847
...
850
851
852
853
854
855
856










857
858
859
860



861

862
863
864


865
866
867
868
869
870
871
872
873
...
984
985
986
987
988
989
990

991
992
993
994
995
996
997
      a = fileRead((ovfl-1)*(sqlite3_int64)g.pagesize, 4);
      ovfl = decodeInt32(a);
      sqlite3_free(a);
    }
  }
}










/*
** Describe the usages of a b-tree page



*/
static void page_usage_btree(
  int pgno,             /* Page to describe */
  int parent,           /* Parent of this page.  0 for root pages */
  int idx,              /* Which child of the parent */
  const char *zName     /* Name of the table */
){
................................................................................
  int nCell;
  int i;
  int hdr = pgno==1 ? 100 : 0;

  if( pgno<=0 || pgno>g.mxPage ) return;
  a = fileRead((pgno-1)*g.pagesize, g.pagesize);
  switch( a[hdr] ){










    case 2:  zType = "interior node of index";  break;
    case 5:  zType = "interior node of table";  break;
    case 10: zType = "leaf of index";           break;
    case 13: zType = "leaf of table";           break;



  }

  if( parent ){
    page_usage_msg(pgno, "%s [%s], child %d of page %d",
                   zType, zName, idx, parent);


  }else{
    page_usage_msg(pgno, "root %s [%s]", zType, zName);
  }
  nCell = a[hdr+3]*256 + a[hdr+4];
  if( a[hdr]==2 || a[hdr]==5 ){
    int cellstart = hdr+12;
    unsigned int child;
    for(i=0; i<nCell; i++){
      int ofst;
................................................................................
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ) break;
  }
  sqlite3_close(db);

  /* Print the report and free memory used */
  for(i=1; i<=g.mxPage; i++){

    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    sqlite3_free(zPageUse[i]);
  }
  sqlite3_free(zPageUse);
  zPageUse = 0;
}








>
>
>
>
>
>
|
>
>

|
>
>
>







 







>
>
>
>
>
>
>
>
>
>




>
>
>
|
>
|


>
>

|







 







>







831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
...
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
....
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
      a = fileRead((ovfl-1)*(sqlite3_int64)g.pagesize, 4);
      ovfl = decodeInt32(a);
      sqlite3_free(a);
    }
  }
}

/*
** True if the memory is all zeros
*/
static int allZero(unsigned char *a, int n){
  while( n && (a++)[0]==0 ){ n--; }
  return n==0;
}


/*
** Describe the usages of a b-tree page.
**
** If parent==0, then this is the root of a btree.  If parent<0 then
** this is an orphan page.
*/
static void page_usage_btree(
  int pgno,             /* Page to describe */
  int parent,           /* Parent of this page.  0 for root pages */
  int idx,              /* Which child of the parent */
  const char *zName     /* Name of the table */
){
................................................................................
  int nCell;
  int i;
  int hdr = pgno==1 ? 100 : 0;

  if( pgno<=0 || pgno>g.mxPage ) return;
  a = fileRead((pgno-1)*g.pagesize, g.pagesize);
  switch( a[hdr] ){
    case 0: {
      if( allZero(a, g.pagesize) ){
        zType = "zeroed page";
      }else if( parent<0 ){
        return;
      }else{
        zType = "corrupt node";
      }
      break;
    }
    case 2:  zType = "interior node of index";  break;
    case 5:  zType = "interior node of table";  break;
    case 10: zType = "leaf of index";           break;
    case 13: zType = "leaf of table";           break;
    default: {
      if( parent<0 ) return;
      zType = "corrupt node";
    }
  }
  if( parent>0 ){
    page_usage_msg(pgno, "%s [%s], child %d of page %d",
                   zType, zName, idx, parent);
  }else if( parent==0 ){
    page_usage_msg(pgno, "root %s [%s]", zType, zName);
  }else{
    page_usage_msg(pgno, "orphaned %s", zType);
  }
  nCell = a[hdr+3]*256 + a[hdr+4];
  if( a[hdr]==2 || a[hdr]==5 ){
    int cellstart = hdr+12;
    unsigned int child;
    for(i=0; i<nCell; i++){
      int ofst;
................................................................................
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ) break;
  }
  sqlite3_close(db);

  /* Print the report and free memory used */
  for(i=1; i<=g.mxPage; i++){
    if( zPageUse[i]==0 ) page_usage_btree(i, -1, 0, 0);
    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    sqlite3_free(zPageUse[i]);
  }
  sqlite3_free(zPageUse);
  zPageUse = 0;
}