Skip to content

Commit 69a2fcf

Browse files
Address Review comments
1 parent dde8a8b commit 69a2fcf

File tree

5 files changed

+60
-56
lines changed

5 files changed

+60
-56
lines changed

storage/innobase/btr/btr0btr.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4103,7 +4103,8 @@ static bool btr_validate_level(
41034103
dict_index_t *index, /*!< in: index tree */
41044104
const trx_t *trx, /*!< in: transaction or NULL */
41054105
ulint level, /*!< in: level number */
4106-
bool lockout) /*!< in: true if X-latch index is intended */
4106+
bool lockout, /*!< in: true if X-latch index is intended */
4107+
blob_ref_map *blob_map = nullptr) /*!< in: Optional blob reference map. */
41074108
{
41084109
buf_block_t *block;
41094110
page_t *page;
@@ -4260,7 +4261,7 @@ static bool btr_validate_level(
42604261

42614262
ret = false;
42624263

4263-
} else if (!page_validate(page, index)) {
4264+
} else if (!page_validate(page, index, blob_map)) {
42644265
btr_validate_report1(index, level, block);
42654266
ret = false;
42664267

@@ -4573,9 +4574,10 @@ static bool btr_validate_spatial_index(
45734574
/** Checks the consistency of an index tree.
45744575
@return true if ok */
45754576
bool btr_validate_index(
4576-
dict_index_t *index, /*!< in: index */
4577-
const trx_t *trx, /*!< in: transaction or NULL */
4578-
bool lockout) /*!< in: true if X-latch index is intended */
4577+
dict_index_t *index, /*!< in: index */
4578+
const trx_t *trx, /*!< in: transaction or NULL */
4579+
bool lockout, /*!< in: true if X-latch index is intended */
4580+
blob_ref_map *blob_map) /*!< in: Optional blob reference map. */
45794581
{
45804582
/* Full Text index are implemented by auxiliary tables,
45814583
not the B-tree */
@@ -4640,7 +4642,7 @@ bool btr_validate_index(
46404642
ulint n = btr_page_get_level(root);
46414643

46424644
for (ulint i = 0; i <= n; ++i) {
4643-
if (!btr_validate_level(index, trx, n - i, lockout)) {
4645+
if (!btr_validate_level(index, trx, n - i, lockout, blob_map)) {
46444646
ok = false;
46454647
break;
46464648
}

storage/innobase/handler/ha_innodb.cc

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18916,18 +18916,16 @@ int ha_innobase::check(THD *thd, /*!< in: user thread handle */
1891618916
CHECK TABLE. */
1891718917
srv_fatal_semaphore_wait_extend.fetch_add(1);
1891818918

18919+
blob_ref_map blob_map;
18920+
blob_ref_map *blob_map_ptr = nullptr;
18921+
1891918922
if (is_extended && index->is_clustered()) {
18920-
// Setup the thread local map for clustered index only
18921-
thread_local_blob_map = new blob_ref_map();
18923+
// Setup the blob map for clustered index only.
18924+
blob_map_ptr = &blob_map;
1892218925
}
1892318926

18924-
auto blob_ref_clear_guard = create_scope_guard([]() {
18925-
if (!thread_local_blob_map) return;
18926-
delete thread_local_blob_map;
18927-
thread_local_blob_map = nullptr;
18928-
});
18929-
18930-
bool valid = btr_validate_index(index, m_prebuilt->trx, false);
18927+
bool valid =
18928+
btr_validate_index(index, m_prebuilt->trx, false, blob_map_ptr);
1893118929

1893218930
/* Restore the fatal lock wait timeout after
1893318931
CHECK TABLE. */

storage/innobase/include/btr0btr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
4141
#include "gis0type.h"
4242
#include "mtr0mtr.h"
4343
#include "page0cur.h"
44+
#include "page0page.h"
4445
#include "univ.i"
4546

4647
/** Maximum record size which can be stored on a page, without using the
@@ -553,7 +554,8 @@ the index.
553554
[[nodiscard]] bool btr_validate_index(
554555
dict_index_t *index, /*!< in: index */
555556
const trx_t *trx, /*!< in: transaction or 0 */
556-
bool lockout); /*!< in: true if X-latch index is intended */
557+
bool lockout, /*!< in: true if X-latch index is intended */
558+
blob_ref_map *blob_map = nullptr); /*!< in: Optional blob reference map. */
557559

558560
/** Creates SDI index and stores the root page numbers in page 1 & 2
559561
@param[in] space_id tablespace id

storage/innobase/include/page0page.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -761,12 +761,22 @@ bool page_simple_validate_old(
761761
bool page_simple_validate_new(
762762
const page_t *page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */
763763

764+
/** A blob map to track the first page no of external LOB and its parent record
765+
which is the <page_no, heap_no>. This is used to find duplicate external LOB
766+
pages that is shared between two records. This can happen only on corruption
767+
(cause unknown yet). CHECK TABLE t1 EXTENDED will use this map to report
768+
corruption and mark the table as corrupted */
769+
using blob_ref_map = std::unordered_map<page_no_t, std::pair<page_no_t, ulint>>;
770+
764771
/** This function checks the consistency of an index page.
765772
@param[in] page index page
766773
@param[in] index data dictionary index containing the page record type
767774
definition
775+
@param[in] blob_map Optional blob reference map for tracking, nullptr by
776+
default.
768777
@return true if ok */
769-
bool page_validate(const page_t *page, dict_index_t *index);
778+
bool page_validate(const page_t *page, dict_index_t *index,
779+
blob_ref_map *blob_map = nullptr);
770780

771781
/** Looks in the page record list for a record with the given heap number.
772782
@return record, NULL if not found */
@@ -802,23 +812,18 @@ param[in] index index
802812
@return true if ok */
803813
bool page_is_spatial_non_leaf(const rec_t *rec, dict_index_t *index);
804814

805-
/** A blob map to track the first page no of external LOB and its parent record
806-
which is the <page_no, heap_no>. This is used to find duplicate external LOB
807-
pages that is shared between two records. This can happen only on corruption
808-
(cause unknown yet). CHECK TABLE t1 EXTENDED will use this map to report
809-
corruption and mark the table as corrupted */
810-
using blob_ref_map = std::unordered_map<page_no_t, std::pair<page_no_t, ulint>>;
811-
extern thread_local blob_ref_map *thread_local_blob_map;
812-
813815
/** Validate that the external LOB's first page is not shared between records of
814816
a clustered index
815817
@param[in] rec physical record
816818
@param[in] index index of the table
817819
@param[in] offsets the record offset array
820+
@param[in] blob_map Optional blob reference map for tracking, nullptr by
821+
default.
818822
@return true If OK else false if external LOB is found to be shared between two
819823
records, ie false on failure */
820824
bool page_rec_blob_validate(const rec_t *rec, const dict_index_t *index,
821-
const ulint *offsets);
825+
const ulint *offsets,
826+
blob_ref_map *blob_map = nullptr);
822827

823828
#include "page0page.ic"
824829

storage/innobase/page/page0page.cc

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
4848
#endif /* !UNIV_HOTBACKUP */
4949
#include "lob0lob.h"
5050

51-
/** A blob map to track the first page no of external LOB and its parent record
52-
which is the <page_no, heap_no>. This is used to find duplicate external LOB
53-
pages that is shared between two records. This can happen only on corruption
54-
(cause unknown yet). CHECK TABLE t1 EXTENDED will use this map to report
55-
corruption and mark the table as corrupted */
56-
thread_local blob_ref_map *thread_local_blob_map = nullptr;
5751

5852
/* THE INDEX PAGE
5953
==============
@@ -1734,47 +1728,49 @@ a clustered index
17341728
@param[in] rec physical record
17351729
@param[in] index index of the table
17361730
@param[in] offsets the record offset array
1731+
@param[in] blob_map Optional blob reference map for tracking, nullptr by
1732+
default.
17371733
@return true If OK else false if external LOB is found to be shared between two
17381734
records, ie false on failure */
17391735
bool page_rec_blob_validate(const rec_t *rec, const dict_index_t *index,
1740-
const ulint *offsets) {
1741-
// this means reference check is not enabled. Enabled only via
1742-
// CHECK TABLE path
1743-
if (thread_local_blob_map == nullptr) {
1736+
const ulint *offsets, blob_ref_map *blob_map) {
1737+
// This means reference check is not enabled. Enabled only via
1738+
// CHECK TABLE path.
1739+
if (blob_map == nullptr) {
17441740
return true;
17451741
}
17461742

1747-
// if index is not PRIMARY, return true
1743+
// If index is not PRIMARY, return true.
17481744
if (!index->is_clustered()) {
17491745
return true;
17501746
}
17511747

1752-
// if page-level is not zero, return true because blob exists only on leaf
1753-
// level
1748+
// If page-level is not zero, return true because blob exists only on leaf
1749+
// level.
17541750
const page_t *page = page_align(rec);
17551751
if (!page_is_leaf(page)) {
17561752
return true;
17571753
}
17581754

1759-
// if rec is not user record, blobs dont exist, return true
1755+
// If rec is not user record, blobs dont exist, return true.
17601756
if (!page_rec_is_user_rec(rec)) {
17611757
return true;
17621758
}
17631759

1764-
// if rec doesn't have any external LOB, return true
1760+
// If rec doesn't have any external LOB, return true.
17651761
if (!rec_offs_any_extern(offsets)) {
17661762
return true;
17671763
}
17681764

1769-
// if rec is deleted marked, return true, we cannot validate the blob. the
1770-
// blob pages in the deleted marked records could be freed
1765+
// If rec is deleted marked, return true, we cannot validate the blob. The
1766+
// blob pages in the deleted marked records could be freed.
17711767
if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
17721768
return true;
17731769
}
17741770

1775-
// if rec is not the owner of the blob, we cannot validate if blob page state
1771+
// If rec is not the owner of the blob, we cannot validate if blob page state
17761772
// now validate that the blob first page is not marked as free from page
1777-
// bitmap
1773+
// bitmap.
17781774

17791775
ulint n_fields = rec_offs_n_fields(offsets);
17801776

@@ -1786,8 +1782,7 @@ bool page_rec_blob_validate(const rec_t *rec, const dict_index_t *index,
17861782
lob::btr_rec_get_field_ref(index, rec, offsets, i));
17871783

17881784
lob::ref_t ref(field_ref);
1789-
if (!ref.is_owner() || ref.is_null() || ref.is_null_relaxed() ||
1790-
ref.is_being_modified()) {
1785+
if (!ref.is_owner() || ref.is_null_relaxed() || ref.is_being_modified()) {
17911786
continue;
17921787
}
17931788

@@ -1816,16 +1811,16 @@ bool page_rec_blob_validate(const rec_t *rec, const dict_index_t *index,
18161811

18171812
DBUG_EXECUTE_IF(
18181813
"simulate_lob_corruption",
1819-
// introduce corruption after 5 external LOB entries
1820-
if (thread_local_blob_map->size() >= 5) {
1821-
// we introduce a fake entry in the map
1822-
(*thread_local_blob_map)[blob_page_no] = std::make_pair(
1814+
// Introduce corruption after 5 external LOB entries.
1815+
if (blob_map->size() >= 5) {
1816+
// We introduce a fake entry in the map.
1817+
(*blob_map)[blob_page_no] = std::make_pair(
18231818
page_get_page_no(page) - 1, page_rec_get_heap_no(rec) - 1);
18241819
});
18251820

1826-
auto it = thread_local_blob_map->find(blob_page_no);
1827-
if (it == thread_local_blob_map->end()) {
1828-
(*thread_local_blob_map)[blob_page_no] =
1821+
auto it = blob_map->find(blob_page_no);
1822+
if (it == blob_map->end()) {
1823+
(*blob_map)[blob_page_no] =
18291824
std::make_pair(page_get_page_no(page), page_rec_get_heap_no(rec));
18301825
} else {
18311826
auto val = it->second;
@@ -2249,7 +2244,8 @@ bool page_is_spatial_non_leaf(const rec_t *rec, dict_index_t *index) {
22492244
return (dict_index_is_spatial(index) && !page_is_leaf(page_align(rec)));
22502245
}
22512246

2252-
bool page_validate(const page_t *page, dict_index_t *index) {
2247+
bool page_validate(const page_t *page, dict_index_t *index,
2248+
blob_ref_map *blob_map) {
22532249
const page_dir_slot_t *slot;
22542250
mem_heap_t *heap;
22552251
byte *buf;
@@ -2360,7 +2356,8 @@ bool page_validate(const page_t *page, dict_index_t *index) {
23602356
goto func_exit;
23612357
}
23622358

2363-
if (!page_rec_blob_validate(const_cast<byte *>(rec), index, offsets)) {
2359+
if (!page_rec_blob_validate(const_cast<byte *>(rec), index, offsets,
2360+
blob_map)) {
23642361
goto func_exit;
23652362
}
23662363

0 commit comments

Comments
 (0)