Merge lp:~akopytov/percona-server/BT27273-file-format-detection-in-innochecksum into lp:percona-server/5.5

Proposed by Alexey Kopytov
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 358
Proposed branch: lp:~akopytov/percona-server/BT27273-file-format-detection-in-innochecksum
Merge into: lp:percona-server/5.5
Diff against target: 160 lines (+92/-3)
1 file modified
Percona-Server/extra/innochecksum.c (+92/-3)
To merge this branch: bzr merge lp:~akopytov/percona-server/BT27273-file-format-detection-in-innochecksum
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+135669@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :

No Jenkins build, as the test suite has no tests for innochecksum anyway.

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Looks good.

Some comments if we ever revisit this for some reason (might be converted to wishlist bugs)
- there is no reason not to test this feature at least minimally. The testcase seems to be straightforward enough as long as we don't care about pre-5.1.7 format.
- mach_read_from_2 should be "static inline"
- display_format_info arg should be const.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Percona-Server/extra/innochecksum.c'
2--- Percona-Server/extra/innochecksum.c 2011-08-22 14:12:27 +0000
3+++ Percona-Server/extra/innochecksum.c 2012-11-22 12:54:22 +0000
4@@ -44,6 +44,27 @@
5 #define FIL_PAGE_SPACE_OR_CHKSUM 0
6 #define UNIV_PAGE_SIZE (2 * 8192)
7
8+#define FIL_PAGE_TYPE 24
9+#define FIL_PAGE_TYPE_FSP_HDR 8 /*!< File space header */
10+/** Offset of the space header within a file page */
11+#define FSP_HEADER_OFFSET 38
12+#define FSP_SPACE_FLAGS 16 /* fsp_space_t.flags, similar to
13+ dict_table_t::flags */
14+/** Smallest compressed page size */
15+#define PAGE_ZIP_MIN_SIZE (1 << 10)
16+
17+#define DICT_TF_BITS 6 /*!< number of flag bits */
18+#define DICT_TF_FORMAT_SHIFT 5 /* file format */
19+#define DICT_TF_FORMAT_MASK \
20+((~(~0 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT))) << DICT_TF_FORMAT_SHIFT)
21+#define DICT_TF_FORMAT_51 0 /*!< InnoDB/MySQL up to 5.1 */
22+#define DICT_TF_FORMAT_ZIP 1 /*!< InnoDB plugin for 5.1:
23+ compressed tables,
24+ new BLOB treatment */
25+#define DICT_TF_ZSSIZE_SHIFT 1
26+#define DICT_TF_ZSSIZE_MASK (15 << DICT_TF_ZSSIZE_SHIFT)
27+#define DICT_TF_ZSSIZE_MAX (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 1)
28+
29 /* command line argument to do page checks (that's it) */
30 /* another argument to specify page ranges... seek to right spot and go from there */
31
32@@ -59,6 +80,11 @@
33 );
34 }
35
36+ulint mach_read_from_2(uchar *b)
37+{
38+ return(((ulint)(b[0]) << 8) | (ulint)(b[1]));
39+}
40+
41 ulint
42 ut_fold_ulint_pair(
43 /*===============*/
44@@ -130,6 +156,56 @@
45 return(checksum);
46 }
47
48+static
49+void
50+display_format_info(uchar *page)
51+{
52+ ulint page_type;
53+ ulint flags;
54+
55+ /* Read page type. Pre-5.1.7 InnoDB always have zero in FIL_PAGE_TYPE for the
56+ first page, later versions initialize it to FIL_PAGE_TYPE_FSP_HDR. */
57+ page_type= mach_read_from_2(page + FIL_PAGE_TYPE);
58+
59+ /* Read FSP flags from the page header. */
60+ flags = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_FLAGS);
61+
62+ if (!page_type)
63+ {
64+ printf("Detected file format: Antelope (pre-5.1.7).\n");
65+ if (flags != 0) {
66+ printf("But FSP_SPACE_FLAGS is non-zero: %lu. Corrupted tablespace?\n",
67+ flags);
68+ }
69+ }
70+ else if (page_type == FIL_PAGE_TYPE_FSP_HDR)
71+ {
72+ ulint format = flags & DICT_TF_FORMAT_MASK >> DICT_TF_FORMAT_SHIFT;
73+ ulint zip_size = ((PAGE_ZIP_MIN_SIZE >> 1)
74+ << ((flags & DICT_TF_ZSSIZE_MASK)
75+ >> DICT_TF_ZSSIZE_SHIFT));
76+
77+ if (!flags)
78+ {
79+ printf("Detected file format: Antelope (5.1.7 or newer).\n");
80+ }
81+ else if (format == DICT_TF_FORMAT_ZIP)
82+ {
83+ printf("Detected file format: Barracuda ");
84+ if (!zip_size)
85+ printf("(not compressed).\n");
86+ else
87+ printf("(compressed with KEY_BLOCK_SIZE=%lu).\n", zip_size);
88+ }
89+ else
90+ printf("Unknown file format: %lu\n", format);
91+ }
92+ else
93+ {
94+ printf("Bogus FIL_PAGE_TYPE value: %lu. Cannot detect the file format.\n",
95+ page_type);
96+ }
97+}
98
99 int main(int argc, char **argv)
100 {
101@@ -146,13 +222,14 @@
102 ulint start_page= 0, end_page= 0, use_end_page= 0; /* for starting and ending at certain pages */
103 off_t offset= 0;
104 int just_count= 0; /* if true, just print page count */
105+ int display_format= 0; /* if true, just print format information */
106 int verbose= 0;
107 int debug= 0;
108 int c;
109 int fd;
110
111 /* remove arguments */
112- while ((c= getopt(argc, argv, "cvds:e:p:")) != -1)
113+ while ((c= getopt(argc, argv, "fcvds:e:p:")) != -1)
114 {
115 switch (c)
116 {
117@@ -181,6 +258,9 @@
118 fprintf(stderr, "option -%c requires an argument\n", optopt);
119 return 1;
120 break;
121+ case 'f':
122+ display_format= 1;
123+ break;
124 case '?':
125 fprintf(stderr, "unrecognized option: -%c\n", optopt);
126 return 1;
127@@ -196,6 +276,7 @@
128 {
129 printf("InnoDB offline file checksum utility.\n");
130 printf("usage: %s [-c] [-s <start page>] [-e <end page>] [-p <page>] [-v] [-d] <filename>\n", argv[0]);
131+ printf("\t-f\tdisplay information about the file format and exit\n");
132 printf("\t-c\tprint the count of pages in the file\n");
133 printf("\t-s n\tstart on this page number (0 based)\n");
134 printf("\t-e n\tend at this page number (0 based)\n");
135@@ -232,8 +313,9 @@
136 return 1;
137 }
138
139- /* seek to the necessary position */
140- if (start_page)
141+ /* seek to the necessary position, ignore with -f as we only need to read the
142+ first page */
143+ if (start_page && !display_format)
144 {
145 fd= fileno(f);
146 if (!fd)
147@@ -267,6 +349,13 @@
148 return 1;
149 }
150
151+ if (display_format)
152+ {
153+ /* for -f, analyze only the first page and exit */
154+ display_format_info(p);
155+ return 0;
156+ }
157+
158 /* check the "stored log sequence numbers" */
159 logseq= mach_read_from_4(p + FIL_PAGE_LSN + 4);
160 logseqfield= mach_read_from_4(p + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM + 4);

Subscribers

People subscribed via source and target branches