Merge lp:~gaul/percona-data-recovery-tool-for-innodb/ibd_rename_ids into lp:percona-data-recovery-tool-for-innodb

Proposed by Andrew Gaul
Status: Approved
Approved by: Aleksandr Kuzminsky
Approved revision: 69
Proposed branch: lp:~gaul/percona-data-recovery-tool-for-innodb/ibd_rename_ids
Merge into: lp:percona-data-recovery-tool-for-innodb
Diff against target: 265 lines (+234/-2)
2 files modified
Makefile (+5/-2)
ibd_rename_ids.c (+229/-0)
To merge this branch: bzr merge lp:~gaul/percona-data-recovery-tool-for-innodb/ibd_rename_ids
Reviewer Review Type Date Requested Status
Percona developers Pending
Review via email: mp+119652@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2012-08-10 01:04:21 +0000
+++ Makefile 2012-08-15 01:14:19 +0000
@@ -4,7 +4,7 @@
44
5INCLUDES=-I include -I mysql-source/include -I mysql-source/innobase/include5INCLUDES=-I include -I mysql-source/include -I mysql-source/innobase/include
66
7all: prerequisites constraints_parser page_parser page_printer innochecksum ibdconnect7all: prerequisites constraints_parser page_parser page_printer innochecksum ibdconnect ibd_rename_ids
88
9prerequisites:9prerequisites:
10 @echo "Make sure you have installed following packages:"10 @echo "Make sure you have installed following packages:"
@@ -51,6 +51,9 @@
51ibdconnect: ibdconnect.c include/ibdconnect.h include/sys_defs.h51ibdconnect: ibdconnect.c include/ibdconnect.h include/sys_defs.h
52 gcc $(CFLAGS) $(INCLUDES) -o $@ $<52 gcc $(CFLAGS) $(INCLUDES) -o $@ $<
5353
54ibd_rename_ids: ibd_rename_ids.c include/innochecksum.h
55 gcc $(CFLAGS) $(INCLUDES) -o $@ $<
56
54dict_parsers: all57dict_parsers: all
55 @mkdir -p bin58 @mkdir -p bin
56 @ln -fs table_defs.h.SYS_TABLES include/table_defs.h59 @ln -fs table_defs.h.SYS_TABLES include/table_defs.h
@@ -93,7 +96,7 @@
93 rm -rf innodb_recovery96 rm -rf innodb_recovery
94 97
95clean: 98clean:
96 rm -f page_parser page_printer constraints_parser innochecksum ibdconnect prerequisites99 rm -f page_parser page_printer constraints_parser innochecksum ibdconnect prerequisites ibd_rename_ids
97 rm -rf lib constraints_parser.dSYM page_parser.dSYM100 rm -rf lib constraints_parser.dSYM page_parser.dSYM
98101
99distclean: clean102distclean: clean
100103
=== added file 'ibd_rename_ids.c'
--- ibd_rename_ids.c 1970-01-01 00:00:00 +0000
+++ ibd_rename_ids.c 2012-08-15 01:14:19 +0000
@@ -0,0 +1,229 @@
1/* Copyright (C) 2000-2005 MySQL AB & Innobase Oy
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15
16/*
17 InnoDB tablespace, table, and index id renamer.
18
19 Written by Andrew Gaul <andrew@gaul.org>.
20
21 Published with permission.
22*/
23
24/* TODO: batch IO */
25/* TODO: requires innodb_file_per_table; confused tablespace and table id */
26
27#include <inttypes.h>
28#include <stdint.h>
29#include <unistd.h>
30#include "page0page.h"
31#include "innochecksum.h"
32
33static void usage(const char *progname)
34{
35 printf("InnoDB tablespace, table, and index id renamer.\n"
36 "usage: %s [OPTIONS]... FILENAME\n"
37 "\t-t ID\tset new tablespace id\n"
38 "\t-I ID\tmap from this index id\n"
39 "\t-i ID\tmap to this index id\n"
40 "\t-v\tverbose output\n",
41 progname);
42}
43
44static uint64_t dulint_to_uint64_t(dulint x)
45{
46 return (((uint64_t) x.high) << 32) | x.low;
47}
48
49static void write_page(FILE *file, fpos_t pos, const uchar *page)
50{
51 if (0 != fsetpos(file, &pos)) {
52 perror("couldn't set a position to the start of the page");
53 exit(1);
54 }
55 if (1 != fwrite(page, UNIV_PAGE_SIZE, 1, file)) {
56 perror("couldn't update the page");
57 exit(1);
58 }
59}
60
61int main(int argc, char **argv)
62{
63 FILE *file = NULL; /* input file */
64 uchar *page = (uchar *)malloc(UNIV_PAGE_SIZE); /* storage for pages read */
65 int bytes; /* bytes read count */
66 ulint page_no = 0; /* current page number (0-based) */
67 int32_t tablespace_id_to = -1;
68 int64_t *index_id_from = malloc(0);
69 size_t index_id_from_size = 0;
70 int64_t *index_id_to = malloc(0);
71 size_t index_id_to_size = 0;
72 int64_t index_id;
73 size_t i;
74 int verbose = 0;
75 int c;
76 char *endptr;
77 fpos_t pos;
78 int retval = EXIT_FAILURE;
79
80 /* parse arguments */
81 while ((c = getopt(argc, argv, "hvt:I:i:")) != -1) {
82 switch (c) {
83 case 'v':
84 verbose = 1;
85 break;
86 case 't':
87 tablespace_id_to = strtol(optarg, &endptr, 10);
88 if (*endptr != '\0') {
89 fprintf(stderr, "invalid value %s\n", optarg);
90 goto out;
91 }
92 break;
93 case 'I':
94 index_id = strtoll(optarg, &endptr, 10);
95 if (*endptr != '\0') {
96 fprintf(stderr, "invalid value %s\n", optarg);
97 goto out;
98 }
99 index_id_from = realloc(index_id_from,
100 sizeof(*index_id_from) * (index_id_from_size + 1));
101 index_id_from[index_id_from_size++] = index_id;
102 break;
103 case 'i':
104 index_id = strtoll(optarg, &endptr, 10);
105 if (*endptr != '\0') {
106 fprintf(stderr, "invalid value %s\n", optarg);
107 goto out;
108 }
109 index_id_to = realloc(index_id_to,
110 sizeof(*index_id_to) * (index_id_to_size + 1));
111 index_id_to[index_id_to_size++] = index_id;
112 break;
113 case ':':
114 fprintf(stderr, "option -%c requires an argument\n", optopt);
115 goto out;
116 case '?':
117 fprintf(stderr, "unrecognized option: -%c\n", optopt);
118 goto out;
119 case 'h':
120 default:
121 usage(argv[0]);
122 goto out;
123 }
124 }
125
126 /* make sure we have the right arguments */
127 if (optind >= argc) {
128 usage(argv[0]);
129 goto out;
130 }
131
132 if (index_id_from_size != index_id_to_size) {
133 fprintf(stderr, "Mismatched -T and -t parameters.\n");
134 goto out;
135 }
136
137 file = fopen(argv[optind], "r+");
138 if (!file) {
139 perror("error opening file");
140 goto out;
141 }
142
143 while (!feof(file)) {
144 fgetpos(file, &pos);
145 bytes = fread(page, 1, UNIV_PAGE_SIZE, file);
146 if (!bytes && feof(file)) break;
147 if (bytes != UNIV_PAGE_SIZE) {
148 fprintf(stderr,
149 "bytes read (%d) does not match universal page size (%d)\n",
150 bytes, UNIV_PAGE_SIZE);
151 goto out;
152 }
153
154 uint16_t type = mach_read_from_2(page + FIL_PAGE_TYPE);
155 uint32_t id = mach_read_from_4((uchar*)&tablespace_id_to);
156 int modified = FALSE;
157 if (type != FIL_PAGE_TYPE_ALLOCATED) {
158 if (tablespace_id_to != -1) {
159 if (verbose) {
160 printf("changing tablespace id from %lu to %u at page %lu\n",
161 mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID),
162 tablespace_id_to, page_no);
163 }
164 memcpy(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, &id, sizeof(id));
165 modified = TRUE;
166 }
167 }
168 if (type == FIL_PAGE_TYPE_FSP_HDR) {
169 if (tablespace_id_to != -1) {
170 memcpy(page + FIL_PAGE_DATA + FSEG_HDR_SPACE, &id, sizeof(id));
171 modified = TRUE;
172 }
173 } else if (type == FIL_PAGE_INDEX) {
174 uint64_t on_disk_index_id = dulint_to_uint64_t(mach_read_from_8(
175 page + FIL_PAGE_DATA + PAGE_INDEX_ID));
176 for (i = 0; i < index_id_from_size; ++i) {
177 if (on_disk_index_id == index_id_from[i]) {
178 if (verbose) {
179 printf("changing index id from %" PRIu64 " to %" PRIi64
180 " at page %lu\n", index_id_from[i], index_id_to[i], page_no);
181 }
182 uint64_t index_id_to_swapped = dulint_to_uint64_t(mach_read_from_8(
183 (uchar*)&index_id_to[i]));
184 memcpy(page + FIL_PAGE_DATA + PAGE_INDEX_ID, &index_id_to_swapped,
185 sizeof(index_id_to_swapped));
186 modified = TRUE;
187 break;
188 }
189 }
190
191 if (tablespace_id_to != -1) {
192 memcpy(page + FIL_PAGE_DATA + FSEG_HDR_SPACE + PAGE_BTR_SEG_LEAF, &id,
193 sizeof(id));
194 memcpy(page + FIL_PAGE_DATA + FSEG_HDR_SPACE + PAGE_BTR_SEG_TOP, &id,
195 sizeof(id));
196 modified = TRUE;
197 }
198 }
199
200 if (modified) {
201 /* recalculate new-style checksum */
202 uint32_t new_checksum = buf_calc_page_new_checksum(page);
203 new_checksum = mach_read_from_4((uchar *)&new_checksum);
204 memcpy(page + FIL_PAGE_SPACE_OR_CHKSUM, &new_checksum,
205 sizeof(new_checksum));
206
207 /* recalculate old-style checksum */
208 uint32_t old_checksum = buf_calc_page_old_checksum(page);
209 old_checksum = mach_read_from_4((uchar *)&old_checksum);
210 memcpy(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, &old_checksum,
211 sizeof(old_checksum));
212
213 write_page(file, pos, page);
214 }
215
216 ++page_no;
217 }
218
219 retval = EXIT_SUCCESS;
220
221out:
222 free(index_id_from);
223 free(index_id_to);
224 free(page);
225 if (file != NULL) {
226 fclose(file);
227 }
228 return retval;
229}

Subscribers

People subscribed via source and target branches