2727#include " mylog0log.h"
2828
2929static char *filepath = nullptr ;
30- static uint opt_verbose = 0 ;
31- bool opt_header_only = false ;
32- ulong opt_stop_lsn = 0 ;
33- ulong opt_start_lsn = 0 ;
30+ bool opt_with_header = false , opt_header_only = false ;
31+ ulong opt_stop_lsn = 0 , opt_start_lsn = 0 ;
3432
3533static void get_options (int *argc, char ***argv);
3634
3735static const char *load_default_groups[] = {" mysqlredo" , " client" , nullptr };
3836
3937static struct my_option my_long_options[] = {
4038 {" help" , ' ?' , " Display this help and exit." , nullptr , nullptr , nullptr , GET_NO_ARG, NO_ARG, 0 , 0 , 0 , nullptr , 0 , nullptr },
41- {" header-only" , ' h' , " Display redo log file's header info only." , nullptr , nullptr , nullptr , GET_NO_ARG, NO_ARG, 0 , 0 , 0 , nullptr , 0 , nullptr },
39+ {" header" , ' h' , " Display redo log file's header info." , nullptr , nullptr , nullptr , GET_NO_ARG, NO_ARG, 0 , 0 , 0 , nullptr , 0 , nullptr },
40+ {" header-only" , ' H' , " Display redo log file's header info only." , nullptr , nullptr , nullptr , GET_NO_ARG, NO_ARG, 0 , 0 , 0 , nullptr , 0 , nullptr },
4241 {" verbose" , ' v' , " More verbose output; (you can use this multiple times to get even more verbose output.)" ,
4342 nullptr , nullptr , nullptr , GET_NO_ARG, NO_ARG, 0 , 0 , 0 , nullptr , 0 , nullptr },
4443 {" start-lsn" , ' b' , " Set start lsn to print" ,
@@ -66,10 +65,13 @@ static bool get_one_option(int optid, const struct my_option *opt,
6665 char *argument) {
6766 switch (optid) {
6867 case ' h' :
68+ opt_with_header = true ;
69+ break ;
70+ case ' H' :
6971 opt_header_only = true ;
7072 break ;
7173 case ' v' :
72- opt_verbose ++;
74+ opt_verbose_output ++;
7375 break ;
7476 case ' V' :
7577 print_version ();
@@ -98,6 +100,11 @@ int main(int argc, char **argv) {
98100 if (load_defaults (" my" , load_default_groups, &argc, &argv, &alloc)) exit (1 );
99101 my_getopt_use_args_separator = false ;
100102
103+ Log_checkpoint_header chpt_header;
104+ lsn_t checkpoint_lsn1 = 0 , checkpoint_lsn2 = 0 ;
105+ lsn_t max_chpt_lsn = 0 , start_chpt_lsn = 0 ;
106+ uint64_t start_chpt_offset, first_block_offset;
107+
101108 get_options (&argc, &argv);
102109
103110 /* Need to call ut_crc32 functions in log_file_header_deserialize() */
@@ -112,7 +119,7 @@ int main(int argc, char **argv) {
112119 }
113120
114121 filepath = argv[0 ];
115- if (opt_verbose ) {
122+ if (opt_verbose_output > 1 ) {
116123 std::cout << " filepath: " << filepath << std::endl;
117124 }
118125
@@ -126,43 +133,57 @@ int main(int argc, char **argv) {
126133 }
127134
128135 /* Deserialize header block */
129- std::cout << " -- Header block" << std::endl;
130136 ret = iblog->deserialize_header ();
131137 if (ret) {
132138 std::cerr << " Error: Failed to parse header." << std::endl;
133139 }
134140
135- std::cout << " filesize: " << iblog-> file_size << std::endl;
136- std::cout << " m_format: " << iblog-> header . m_format << std::endl;
137- std::cout << " m_start_lsn: " << iblog-> header . m_start_lsn << std::endl;
138- std::cout << " m_creater_name : " << iblog->header . m_creator_name << std::endl;
139-
140- std::cout << " -- Checkpoint blocks " << std::endl;
141- Log_checkpoint_header chpt_header ;
142- lsn_t max_chpt_lsn = 0 ;
141+ /* Print header block info */
142+ if (opt_with_header || opt_header_only) {
143+ std::cout << " -- Header block " << std::endl;
144+ std::cout << " filesize : " << iblog->file_size << std::endl;
145+ std::cout << " m_format: " << iblog-> header . m_format << std::endl;
146+ std::cout << " m_start_lsn: " << iblog-> header . m_start_lsn << std::endl;
147+ std::cout << " m_creater_name: " << iblog-> header . m_creator_name << std::endl ;
148+ }
143149
144150 /* Deserialize checkpoint block 1 */
145151 if (!log_checkpoint_header_deserialize (iblog->buf + OS_FILE_LOG_BLOCK_SIZE, chpt_header)) {
146152 std::cout << " Error: redo log corrupted." << std::endl;
147153 }
148- std::cout << " checkpoint 1: " << chpt_header.m_checkpoint_lsn << std::endl;
149- if (max_chpt_lsn < chpt_header.m_checkpoint_lsn ) {
150- max_chpt_lsn = chpt_header.m_checkpoint_lsn ;
151- }
154+ checkpoint_lsn1 = chpt_header.m_checkpoint_lsn ;
152155
153156 /* Deserialize checkpoint block 2 */
154157 if (!log_checkpoint_header_deserialize (iblog->buf + OS_FILE_LOG_BLOCK_SIZE*3 , chpt_header)) {
155158 std::cout << " Error: redo log corrupted." << std::endl;
156159 }
157- std::cout << " checkpoint 2: " << chpt_header.m_checkpoint_lsn << std::endl;
158- if (max_chpt_lsn < chpt_header.m_checkpoint_lsn ) {
159- max_chpt_lsn = chpt_header.m_checkpoint_lsn ;
160+ checkpoint_lsn2 = chpt_header.m_checkpoint_lsn ;
161+
162+ // max_checkpoint_lsn
163+ if (checkpoint_lsn1 > checkpoint_lsn2) {
164+ max_chpt_lsn = checkpoint_lsn1;
165+ } else {
166+ max_chpt_lsn = checkpoint_lsn2;
160167 }
161168
162169 /* Calculate start_lsn offset */
163- uint64_t first_block_offset = iblog->get_offset (ut_uint64_align_down (max_chpt_lsn, OS_FILE_LOG_BLOCK_SIZE), iblog->header .m_start_lsn );
164- uint64_t max_chpt_offset = iblog->get_offset (max_chpt_lsn, iblog->header .m_start_lsn );
165- std::cout << " first_block_offset: " << first_block_offset << std::endl;
170+ first_block_offset = iblog->get_offset (ut_uint64_align_down (max_chpt_lsn, OS_FILE_LOG_BLOCK_SIZE), iblog->header .m_start_lsn );
171+
172+ /* Print checkpoint blocks info */
173+ if (opt_with_header || opt_header_only) {
174+ std::cout << " -- Checkpoint blocks" << std::endl;
175+ std::cout << " checkpoint 1: " << checkpoint_lsn1 << std::endl;
176+ std::cout << " checkpoint 2: " << checkpoint_lsn2 << std::endl;
177+ std::cout << " first_block_offset: " << first_block_offset << std::endl;
178+ }
179+ if (opt_header_only) {
180+ return 0 ;
181+ }
182+
183+ /* overwrite first_block_offset */
184+ if (opt_start_lsn) {
185+ first_block_offset = iblog->get_offset (ut_uint64_align_down (opt_start_lsn, OS_FILE_LOG_BLOCK_SIZE), iblog->header .m_start_lsn );
186+ }
166187
167188 /* Read the block including checkpoint lsn */
168189 Log_data_block_header block_header;
@@ -176,21 +197,11 @@ int main(int argc, char **argv) {
176197 recv_sys_init (); /* initialize recv_sys */
177198 dict_persist_init ();
178199
179- /* set start/stop_lsn */
180- if (opt_start_lsn) {
181- recv_sys->start_lsn = opt_start_lsn;
182- } else {
183- recv_sys->start_lsn = ut_uint64_align_down (max_chpt_lsn, OS_FILE_LOG_BLOCK_SIZE) + block_header.m_first_rec_group ;
184- }
185- if (opt_verbose) {
200+ if (opt_verbose_output > 1 ) {
186201 std::cout << " recv_sys->parse_start_lsn: " << ut_uint64_align_down (max_chpt_lsn, OS_FILE_LOG_BLOCK_SIZE) + block_header.m_first_rec_group << std::endl;
187202 }
188203 recv_sys->stop_lsn = opt_stop_lsn;
189204
190- if (opt_header_only) {
191- return 0 ;
192- }
193-
194205 std::cout << " -- Normal blocks" << std::endl;
195206
196207 // initialize recv_sys->buf related by myself
@@ -199,13 +210,24 @@ int main(int argc, char **argv) {
199210 recv_sys->buf = static_cast <byte *>(
200211 ut::malloc_withkey (UT_NEW_THIS_FILE_PSI_KEY, recv_sys->buf_len ));
201212
202- // // copy buf to recv_sys->buf
203- // ut_memcpy(recv_sys->buf, iblog->buf, iblog->file_size);
204-
205-
206213 srv_log_buffer_size = iblog->file_size ;
207214 // modify recv_recovery_begin
208- bool finished = my_parse_begin (iblog->buf , max_chpt_lsn, max_chpt_lsn + iblog->file_size - max_chpt_offset, first_block_offset);
215+ if (opt_start_lsn != 0 ) {
216+ start_chpt_lsn = opt_start_lsn;
217+ start_chpt_offset = iblog->get_offset (start_chpt_lsn, iblog->header .m_start_lsn );
218+ } else {
219+ start_chpt_lsn = max_chpt_lsn;
220+ start_chpt_offset = iblog->get_offset (max_chpt_lsn, iblog->header .m_start_lsn );
221+ }
222+ if (opt_verbose_output) {
223+ std::cout << " start parsing from lsn of " << start_chpt_lsn << " (" << (start_chpt_lsn - start_chpt_lsn % 512 ) << " )" ;
224+ if (opt_stop_lsn) {
225+ std::cout << " to " << opt_stop_lsn;
226+ }
227+ std::cout << std::endl;
228+ }
229+
230+ bool finished = my_parse_begin (iblog->buf , start_chpt_lsn, start_chpt_lsn + iblog->file_size - start_chpt_offset, first_block_offset);
209231 if (!finished) {
210232 std::cerr << " Parse finished in the middle of file." << std::endl;
211233 }
0 commit comments