@@ -378,6 +378,22 @@ Status TabletManager::put_bundle_tablet_metadata(std::map<int64_t, TabletMetadat
378378 return Status::OK ();
379379}
380380
381+ Status TabletManager::corrupted_tablet_meta_handler (const Status& s, const std::string& metadata_location) {
382+ if (s.is_corruption () && config::lake_clear_corrupted_cache) {
383+ auto drop_status = drop_local_cache (metadata_location);
384+ TEST_SYNC_POINT_CALLBACK (" TabletManager::corrupted_tablet_meta_handler" , &drop_status);
385+ if (!drop_status.ok ()) {
386+ LOG (WARNING ) << " clear corrupted cache for " << metadata_location << " failed, "
387+ << " error: " << drop_status;
388+ return s; // return error so load tablet meta can be retried
389+ }
390+ LOG (INFO ) << " clear corrupted cache for " << metadata_location;
391+ return Status::OK ();
392+ } else {
393+ return s;
394+ }
395+ }
396+
381397StatusOr<TabletMetadataPtr> TabletManager::load_tablet_metadata (const string& metadata_location, bool fill_cache,
382398 int64_t expected_gtid,
383399 const std::shared_ptr<FileSystem>& fs) {
@@ -387,21 +403,11 @@ StatusOr<TabletMetadataPtr> TabletManager::load_tablet_metadata(const string& me
387403 ProtobufFile file (metadata_location, fs);
388404 auto s = file.load (metadata.get (), fill_cache);
389405 if (!s.ok ()) {
390- if (s.is_corruption () && config::lake_clear_corrupted_cache) {
391- auto drop_status = drop_local_cache (metadata_location);
392- if (!drop_status.ok ()) {
393- LOG (WARNING ) << " clear corrupted cache for " << metadata_location << " failed, "
394- << " error: " << drop_status;
395- return s; // return error so load tablet meta can be retried
396- }
397- LOG (INFO ) << " clear corrupted cache for " << metadata_location;
398- // reset metadata
399- metadata = std::make_shared<TabletMetadataPB>();
400- // read again
401- RETURN_IF_ERROR (file.load (metadata.get (), fill_cache));
402- } else {
403- return s;
404- }
406+ RETURN_IF_ERROR (corrupted_tablet_meta_handler (s, metadata_location));
407+ // reset metadata
408+ metadata = std::make_shared<TabletMetadataPB>();
409+ // read again
410+ RETURN_IF_ERROR (file.load (metadata.get (), fill_cache));
405411 }
406412
407413 if (expected_gtid > 0 && metadata->gtid () > 0 && expected_gtid != metadata->gtid ()) {
@@ -502,7 +508,13 @@ StatusOr<BundleTabletMetadataPtr> TabletManager::parse_bundle_tablet_metadata(co
502508 std::string_view (serialized_string.data () + file_size - footer_size - bundle_metadata_size);
503509 RETURN_IF (!bundle_metadata->ParseFromArray (bundle_metadata_str.data (), bundle_metadata_size),
504510 Status::Corruption (strings::Substitute (" deserialized shared metadata failed" )));
505-
511+ #ifdef BE_TEST
512+ bool inject_error = false ;
513+ TEST_SYNC_POINT_CALLBACK (" TabletManager::parse_bundle_tablet_metadata::corruption" , &inject_error);
514+ if (inject_error) {
515+ return Status::Corruption (" injected error" );
516+ }
517+ #endif
506518 return bundle_metadata;
507519}
508520
@@ -581,7 +593,18 @@ StatusOr<TabletMetadataPtr> TabletManager::get_single_tablet_metadata(int64_t ta
581593 g_read_bundle_tablet_meta_latency << (butil::gettimeofday_us () - t0);
582594
583595 auto file_size = serialized_string.size ();
584- ASSIGN_OR_RETURN (auto bundle_metadata, parse_bundle_tablet_metadata (path, serialized_string));
596+ BundleTabletMetadataPtr bundle_metadata;
597+ auto bundle_metadata_status = parse_bundle_tablet_metadata (path, serialized_string);
598+ if (!bundle_metadata_status.ok ()) {
599+ RETURN_IF_ERROR (corrupted_tablet_meta_handler (bundle_metadata_status.status (), path));
600+ // read bundle metadata again
601+ ASSIGN_OR_RETURN (auto input_file, file_system->new_random_access_file (opts, path));
602+ ASSIGN_OR_RETURN (serialized_string, input_file->read_all ());
603+ file_size = serialized_string.size ();
604+ ASSIGN_OR_RETURN (bundle_metadata, parse_bundle_tablet_metadata (path, serialized_string));
605+ } else {
606+ bundle_metadata = bundle_metadata_status.value ();
607+ }
585608
586609 auto meta_it = bundle_metadata->tablet_meta_pages ().find (tablet_id);
587610 size_t offset = 0 ;
0 commit comments