Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhance the showdb tool with options to show PTRMAP usage and content. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
06bd91305ed6752315c5224be5f89e87 |
User & Date: | drh 2013-02-19 22:26:51.195 |
Context
2013-02-20
| ||
00:54 | On Minix, disable the ".timer" command in the shell in order to avoid calling getrusage(). (check-in: 9bd9bd9cab user: drh tags: trunk) | |
2013-02-19
| ||
22:26 | Enhance the showdb tool with options to show PTRMAP usage and content. (check-in: 06bd91305e user: drh tags: trunk) | |
20:25 | Fix the showdb utility so that it displays the correct secondary usage of a page when reporting on an error of a page being used more than once. (check-in: 4507f0b3d4 user: drh tags: trunk) | |
Changes
Changes to tool/showdb.c.
︙ | ︙ | |||
610 611 612 613 614 615 616 617 618 619 620 621 622 623 | i, pgno); } free(a); parent = pgno; pgno = iNext; } } /* ** Try to figure out how every page in the database file is being used. */ static void page_usage_report(const char *zDbName){ int i, j; int rc; | > > > > > > > > > > > > > > > > | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | i, pgno); } free(a); parent = pgno; pgno = iNext; } } /* ** Determine pages used as PTRMAP pages */ static void page_usage_ptrmap(unsigned char *a){ if( a[55] ){ int usable = pagesize - a[20]; int pgno = 2; int perPage = usable/5; while( pgno<=mxPage ){ page_usage_msg(pgno, "PTRMAP page covering %d..%d", pgno+1, pgno+perPage); pgno += perPage + 1; } } } /* ** Try to figure out how every page in the database file is being used. */ static void page_usage_report(const char *zDbName){ int i, j; int rc; |
︙ | ︙ | |||
645 646 647 648 649 650 651 652 653 654 655 656 657 658 | zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) ); if( zPageUse==0 ) out_of_memory(); memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1)); /* Discover the usage of each page */ a = getContent(0, 100); page_usage_freelist(decodeInt32(a+32)); free(a); page_usage_btree(1, 0, 0, "sqlite_master"); sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0); for(j=0; j<2; j++){ sqlite3_snprintf(sizeof(zQuery), zQuery, "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage" " ORDER BY rowid %s", j?"DESC":""); | > | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) ); if( zPageUse==0 ) out_of_memory(); memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1)); /* Discover the usage of each page */ a = getContent(0, 100); page_usage_freelist(decodeInt32(a+32)); page_usage_ptrmap(a); free(a); page_usage_btree(1, 0, 0, "sqlite_master"); sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0); for(j=0; j<2; j++){ sqlite3_snprintf(sizeof(zQuery), zQuery, "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage" " ORDER BY rowid %s", j?"DESC":""); |
︙ | ︙ | |||
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | for(i=1; i<=mxPage; i++){ printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???"); sqlite3_free(zPageUse[i]); } sqlite3_free(zPageUse); zPageUse = 0; } /* ** Print a usage comment */ static void usage(const char *argv0){ fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0); fprintf(stderr, "args:\n" " dbheader Show database header\n" " pgidx Index of how each page is used\n" " NNN..MMM Show hex of pages NNN through MMM\n" " NNN..end Show hex of pages NNN through end of file\n" " NNNb Decode btree page NNN\n" " NNNbc Decode btree page NNN and show content\n" " NNNbm Decode btree page NNN and show a layout map\n" " NNNt Decode freelist trunk page NNN\n" " NNNtd Show leaf freelist pages on the decode\n" | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | for(i=1; i<=mxPage; i++){ printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???"); sqlite3_free(zPageUse[i]); } sqlite3_free(zPageUse); zPageUse = 0; } /* ** Try to figure out how every page in the database file is being used. */ static void ptrmap_coverage_report(const char *zDbName){ unsigned int pgno; unsigned char *aHdr; unsigned char *a; int usable; int perPage; unsigned int i; /* Avoid the pathological case */ if( mxPage<1 ){ printf("empty database\n"); return; } /* Make sure PTRMAPs are used in this database */ aHdr = getContent(0, 100); if( aHdr[55]==0 ){ printf("database does not use PTRMAP pages\n"); return; } usable = pagesize - aHdr[20]; perPage = usable/5; free(aHdr); printf("%5d: root of sqlite_master\n", 1); for(pgno=2; pgno<=mxPage; pgno += perPage+1){ printf("%5d: PTRMAP page covering %d..%d\n", pgno, pgno+1, pgno+perPage); a = getContent((pgno-1)*pagesize, usable); for(i=0; i+5<=usable && pgno+1+i/5<=mxPage; i+=5){ const char *zType = "???"; unsigned int iFrom = decodeInt32(&a[i+1]); switch( a[i] ){ case 1: zType = "b-tree root page"; break; case 2: zType = "freelist page"; break; case 3: zType = "first page of overflow"; break; case 4: zType = "later page of overflow"; break; case 5: zType = "b-tree non-root page"; break; } printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom); } free(a); } } /* ** Print a usage comment */ static void usage(const char *argv0){ fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0); fprintf(stderr, "args:\n" " dbheader Show database header\n" " pgidx Index of how each page is used\n" " ptrmap Show all PTRMAP page content\n" " NNN..MMM Show hex of pages NNN through MMM\n" " NNN..end Show hex of pages NNN through end of file\n" " NNNb Decode btree page NNN\n" " NNNbc Decode btree page NNN and show content\n" " NNNbm Decode btree page NNN and show a layout map\n" " NNNt Decode freelist trunk page NNN\n" " NNNtd Show leaf freelist pages on the decode\n" |
︙ | ︙ | |||
732 733 734 735 736 737 738 739 740 741 742 743 744 745 | if( strcmp(argv[i], "dbheader")==0 ){ print_db_header(); continue; } if( strcmp(argv[i], "pgidx")==0 ){ page_usage_report(argv[1]); continue; } if( !isdigit(argv[i][0]) ){ fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]); continue; } iStart = strtol(argv[i], &zLeft, 0); if( zLeft && strcmp(zLeft,"..end")==0 ){ | > > > > > > > > | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 | if( strcmp(argv[i], "dbheader")==0 ){ print_db_header(); continue; } if( strcmp(argv[i], "pgidx")==0 ){ page_usage_report(argv[1]); continue; } if( strcmp(argv[i], "ptrmap")==0 ){ ptrmap_coverage_report(argv[1]); continue; } if( strcmp(argv[i], "help")==0 ){ usage(argv[0]); continue; } if( !isdigit(argv[i][0]) ){ fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]); continue; } iStart = strtol(argv[i], &zLeft, 0); if( zLeft && strcmp(zLeft,"..end")==0 ){ |
︙ | ︙ |