Skip to content

Commit

Permalink
fix(tianmu): mysqld server crash when large amount hash join (stonea…
Browse files Browse the repository at this point in the history
…tom#1110)

    Causes of the crash:
        When the hash join is executed,
        the cache data will be written to the disk.
        If the cache data is written beyond the int type boundary,
        overflow will occur and the service will crash
    Test method:
        When tested locally,
        crashes occur only when the write disk cache exceeds 14GB or so.
        This amount of data is not suitable for testing in MTR
  • Loading branch information
adofsauron authored and konghaiya committed Mar 7, 2023
1 parent 287fd65 commit 33fc150
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 14 deletions.
14 changes: 7 additions & 7 deletions storage/tianmu/core/index_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,25 +121,25 @@ void IndexTable::LoadBlock(int b) {
block_changed = false;
}

void IndexTable::ExpandTo(int64_t new_size) {
void IndexTable::ExpandTo(uint64_t new_size) {
DEBUG_ASSERT(IsLocked());
if (new_size <= (int64_t)size)
if (new_size <= (uint64_t)size)
return;
if (size * bytes_per_value == buffer_size_in_bytes) { // the whole table was in one buffer
if (buffer_size_in_bytes < 32_MB && size_t(new_size * bytes_per_value) > 32_MB) {
max_buffer_size_in_bytes =
int(mm::TraceableObject::MaxBufferSize(-1)); // recalculate, as it might not be done earlier
CI_SetDefaultSize((int)max_buffer_size_in_bytes); // redefine disk block sized
uint64_t(mm::TraceableObject::MaxBufferSize(-1)); // recalculate, as it might not be done earlier
CI_SetDefaultSize((uint64_t)max_buffer_size_in_bytes); // redefine disk block sized
uint values_per_block = uint(max_buffer_size_in_bytes / bytes_per_value);
block_shift =
CalculateBinSize(values_per_block) - 1; // e.g. BinSize(16)==5, but shift by 4. WARNING: should it be
// (val...-1)? Now it works, because v... is only 2^25, 2^24, 2^23
block_mask = (uint64_t(1) << block_shift) - 1;
}

int new_buffer_size_in_bytes;
if (new_size * bytes_per_value < (int64_t)max_buffer_size_in_bytes)
new_buffer_size_in_bytes = int(new_size * bytes_per_value);
uint64_t new_buffer_size_in_bytes;
if (new_size * bytes_per_value < (uint64_t)max_buffer_size_in_bytes)
new_buffer_size_in_bytes = uint64_t(new_size * bytes_per_value);
else
new_buffer_size_in_bytes = max_buffer_size_in_bytes;
// TODO: check the rc_alloc status
Expand Down
6 changes: 3 additions & 3 deletions storage/tianmu/core/index_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class IndexTable : private system::CacheableItem, public mm::TraceableObject {
// which may occur in table
uint64_t N() { return size; } // note: this is the upper size, the table can be used partially!
int BlockShift() { return block_shift; } // block = int( tuple >> block_shift )
void ExpandTo(int64_t new_size);
void ExpandTo(uint64_t new_size);

// mm::TraceableObject functionality
mm::TO_TYPE TraceableType() const override { return mm::TO_TYPE::TO_INDEXTABLE; }
Expand All @@ -118,10 +118,10 @@ class IndexTable : private system::CacheableItem, public mm::TraceableObject {

unsigned char *buf = nullptr; // polymorphic: unsigned short, unsigned int or int64_t

int max_buffer_size_in_bytes;
uint64_t max_buffer_size_in_bytes;
int bytes_per_value;
int max_block_used;
size_t buffer_size_in_bytes;
uint64_t buffer_size_in_bytes;
int block_shift;
uint64_t block_mask;
uint64_t size;
Expand Down
4 changes: 2 additions & 2 deletions storage/tianmu/core/multi_index_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class MultiIndexBuilder {

IndexTable *ReleaseIndexTable(int dim);
bool NullExisted(int dim) const { return nulls_possible_[dim]; }
int GetCount() const { return added_count_; }
uint64_t GetCount() const { return added_count_; }
bool IsEmpty() const { return (added_count_ == 0) ? true : false; }

private:
Expand All @@ -59,7 +59,7 @@ class MultiIndexBuilder {
std::vector<int64_t> cached_values_;
std::vector<bool> nulls_possible_;

int added_count_ = 0;
uint64_t added_count_ = 0;
IndexTable **index_table_;
std::unique_ptr<MINewContentsRSorter> rough_sorter_;
};
Expand Down
4 changes: 2 additions & 2 deletions storage/tianmu/system/cacheable_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CacheableItem {
// or its subrange from position 'off', of length 'size' bytes.
// Returns 0 if successfully got the (sub)block, -1 otherwise

void CI_SetDefaultSize(int size) // If the value is set (here, or in constructor),
void CI_SetDefaultSize(uint64_t size) // If the value is set (here, or in constructor),
{
default_block_size_ = size;
} // then the size parameter in CI_Put may be omitted.
Expand All @@ -73,7 +73,7 @@ class CacheableItem {
std::vector<int> file_start_; // an address in the file where the i-th data block starts
std::vector<int> file_size_; // a size of the i-th data block

int default_block_size_ = 0;
uint64_t default_block_size_ = 0;
TianmuFile cur_file_handle_;
int cur_file_number_ = -1; // the number of currently opened file
void *cur_map_addr_ = nullptr;
Expand Down

0 comments on commit 33fc150

Please sign in to comment.