Use small temp files in direct load
This commit is contained in:
		@ -41,7 +41,13 @@ bool ObDirectLoadExternalMultiPartitionTableBuildParam::is_valid() const
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
ObDirectLoadExternalMultiPartitionTableBuilder::ObDirectLoadExternalMultiPartitionTableBuilder()
 | 
			
		||||
  : allocator_("TLD_EMPTBuilder"), row_count_(0), is_closed_(false), is_inited_(false)
 | 
			
		||||
  : allocator_("TLD_EMPTBuilder"),
 | 
			
		||||
    fragment_array_(),
 | 
			
		||||
    total_row_count_(0),
 | 
			
		||||
    fragment_row_count_(0),
 | 
			
		||||
    max_data_block_size_(0),
 | 
			
		||||
    is_closed_(false),
 | 
			
		||||
    is_inited_(false)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -62,11 +68,8 @@ int ObDirectLoadExternalMultiPartitionTableBuilder::init(
 | 
			
		||||
  } else {
 | 
			
		||||
    param_ = param;
 | 
			
		||||
    allocator_.set_tenant_id(MTL_ID());
 | 
			
		||||
    int64_t dir_id = -1;
 | 
			
		||||
    if (OB_FAIL(param.file_mgr_->alloc_dir(dir_id))) {
 | 
			
		||||
      LOG_WARN("fail to alloc dir", KR(ret));
 | 
			
		||||
    } else if (OB_FAIL(param.file_mgr_->alloc_file(dir_id, file_handle_))) {
 | 
			
		||||
      LOG_WARN("fail to alloc fragment", KR(ret));
 | 
			
		||||
    if (OB_FAIL(alloc_tmp_file())) {
 | 
			
		||||
      LOG_WARN("fail to alloc tmp file", KR(ret));
 | 
			
		||||
    } else if (OB_FAIL(external_writer_.init(param_.table_data_desc_.external_data_block_size_,
 | 
			
		||||
                                             param_.table_data_desc_.compressor_type_,
 | 
			
		||||
                                             param_.extra_buf_, param_.extra_buf_size_))) {
 | 
			
		||||
@ -103,7 +106,62 @@ int ObDirectLoadExternalMultiPartitionTableBuilder::append_row(const ObTabletID
 | 
			
		||||
    } else if (OB_FAIL(external_writer_.write_item(row_))) {
 | 
			
		||||
      LOG_WARN("fail to write item", KR(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      ++row_count_;
 | 
			
		||||
      ++fragment_row_count_;
 | 
			
		||||
      ++total_row_count_;
 | 
			
		||||
    }
 | 
			
		||||
    if (OB_SUCC(ret) && (external_writer_.get_file_size() >= MAX_TMP_FILE_SIZE)) {
 | 
			
		||||
      if (OB_FAIL(switch_fragment())) {
 | 
			
		||||
        LOG_WARN("fail to switch fragment", KR(ret));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObDirectLoadExternalMultiPartitionTableBuilder::alloc_tmp_file()
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  int64_t dir_id = -1;
 | 
			
		||||
  if (OB_FAIL(param_.file_mgr_->alloc_dir(dir_id))) {
 | 
			
		||||
    LOG_WARN("fail to alloc dir", KR(ret));
 | 
			
		||||
  } else if (OB_FAIL(param_.file_mgr_->alloc_file(dir_id, file_handle_))) {
 | 
			
		||||
    LOG_WARN("fail to alloc file", KR(ret));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObDirectLoadExternalMultiPartitionTableBuilder::generate_fragment()
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  ObDirectLoadExternalFragment fragment;
 | 
			
		||||
  fragment.file_size_ = external_writer_.get_file_size();
 | 
			
		||||
  fragment.row_count_ = fragment_row_count_;
 | 
			
		||||
  fragment.max_data_block_size_ = external_writer_.get_max_block_size();
 | 
			
		||||
  if (OB_FAIL(fragment.file_handle_.assign(file_handle_))) {
 | 
			
		||||
    LOG_WARN("fail to assign file handle", KR(ret));
 | 
			
		||||
  } else if (OB_FAIL(fragment_array_.push_back(fragment))) {
 | 
			
		||||
    LOG_WARN("fail to push back fragment", KR(ret));
 | 
			
		||||
  } else if (max_data_block_size_ < fragment.max_data_block_size_) {
 | 
			
		||||
    max_data_block_size_ = fragment.max_data_block_size_;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObDirectLoadExternalMultiPartitionTableBuilder::switch_fragment()
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_FAIL(external_writer_.close())) {
 | 
			
		||||
    LOG_WARN("fail to close external writer", KR(ret));
 | 
			
		||||
  } else if (OB_FAIL(generate_fragment())) {
 | 
			
		||||
    LOG_WARN("fail to generate fragment", KR(ret));
 | 
			
		||||
  } else if (OB_FAIL(alloc_tmp_file())) {
 | 
			
		||||
    LOG_WARN("fail to alloc tmp file", KR(ret));
 | 
			
		||||
  } else {
 | 
			
		||||
    external_writer_.reuse();
 | 
			
		||||
    if (OB_FAIL(external_writer_.open(file_handle_))) {
 | 
			
		||||
      LOG_WARN("fail to open file", KR(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      fragment_row_count_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
@ -118,13 +176,18 @@ int ObDirectLoadExternalMultiPartitionTableBuilder::close()
 | 
			
		||||
  } else if (OB_UNLIKELY(is_closed_)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("direct load external multi partition table is closed", KR(ret));
 | 
			
		||||
  } else {
 | 
			
		||||
    if (OB_FAIL(external_writer_.close())) {
 | 
			
		||||
      LOG_WARN("fail to close external writer", KR(ret));
 | 
			
		||||
  } else if (OB_FAIL(external_writer_.close())) {
 | 
			
		||||
    LOG_WARN("fail to close external writer", KR(ret));
 | 
			
		||||
  } else if ((fragment_row_count_ > 0) || fragment_array_.empty()) {
 | 
			
		||||
    if (OB_FAIL(generate_fragment())) {
 | 
			
		||||
      LOG_WARN("failed to generate fragment", KR(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      is_closed_ = true;
 | 
			
		||||
      fragment_row_count_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
    is_closed_ = true;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -142,18 +205,11 @@ int ObDirectLoadExternalMultiPartitionTableBuilder::get_tables(
 | 
			
		||||
    ObDirectLoadExternalTableCreateParam create_param;
 | 
			
		||||
    create_param.tablet_id_ = 0; //因为包含了所有的tablet_id,设置为一个无效值
 | 
			
		||||
    create_param.data_block_size_ = param_.table_data_desc_.external_data_block_size_;
 | 
			
		||||
    create_param.row_count_ = row_count_;
 | 
			
		||||
    create_param.max_data_block_size_ = external_writer_.get_max_block_size();
 | 
			
		||||
    ObDirectLoadExternalFragment fragment;
 | 
			
		||||
    fragment.file_size_ = external_writer_.get_file_size();
 | 
			
		||||
    fragment.row_count_ = row_count_;
 | 
			
		||||
    fragment.max_data_block_size_ = external_writer_.get_max_block_size();
 | 
			
		||||
    if (OB_FAIL(fragment.file_handle_.assign(file_handle_))) {
 | 
			
		||||
      LOG_WARN("fail to assign file handle", KR(ret));
 | 
			
		||||
    } else if (OB_FAIL(create_param.fragments_.push_back(fragment))) {
 | 
			
		||||
      LOG_WARN("fail to push back", KR(ret));
 | 
			
		||||
    }
 | 
			
		||||
    if (OB_SUCC(ret)) {
 | 
			
		||||
    create_param.row_count_ = total_row_count_;
 | 
			
		||||
    create_param.max_data_block_size_ = max_data_block_size_;
 | 
			
		||||
    if (OB_FAIL(create_param.fragments_.assign(fragment_array_))) {
 | 
			
		||||
      LOG_WARN("fail to assign fragment array", KR(ret), K(fragment_array_));
 | 
			
		||||
    } else {
 | 
			
		||||
      ObDirectLoadExternalTable *external_table = nullptr;
 | 
			
		||||
      if (OB_ISNULL(external_table = OB_NEWx(ObDirectLoadExternalTable, (&allocator)))) {
 | 
			
		||||
        ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
 | 
			
		||||
@ -9,12 +9,12 @@
 | 
			
		||||
#include "storage/direct_load/ob_direct_load_external_multi_partition_row.h"
 | 
			
		||||
#include "storage/direct_load/ob_direct_load_i_table.h"
 | 
			
		||||
#include "storage/direct_load/ob_direct_load_table_data_desc.h"
 | 
			
		||||
#include "storage/direct_load/ob_direct_load_external_fragment.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
namespace storage
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
struct ObDirectLoadExternalMultiPartitionTableBuildParam
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@ -35,6 +35,7 @@ class ObDirectLoadExternalMultiPartitionTableBuilder : public ObIDirectLoadParti
 | 
			
		||||
{
 | 
			
		||||
  typedef ObDirectLoadExternalMultiPartitionRow RowType;
 | 
			
		||||
  typedef ObDirectLoadExternalBlockWriter<RowType> ExternalWriter;
 | 
			
		||||
  static const int64_t MAX_TMP_FILE_SIZE = 1LL * 1024 * 1024 * 1024; // 1GiB
 | 
			
		||||
public:
 | 
			
		||||
  ObDirectLoadExternalMultiPartitionTableBuilder();
 | 
			
		||||
  virtual ~ObDirectLoadExternalMultiPartitionTableBuilder();
 | 
			
		||||
@ -42,16 +43,23 @@ public:
 | 
			
		||||
  int append_row(const common::ObTabletID &tablet_id,
 | 
			
		||||
                 const blocksstable::ObDatumRow &datum_row) override;
 | 
			
		||||
  int close() override;
 | 
			
		||||
  int64_t get_row_count() const override { return row_count_; }
 | 
			
		||||
  int64_t get_row_count() const override { return total_row_count_; }
 | 
			
		||||
  int get_tables(common::ObIArray<ObIDirectLoadPartitionTable *> &table_array,
 | 
			
		||||
                 common::ObIAllocator &allocator) override;
 | 
			
		||||
private:
 | 
			
		||||
  int alloc_tmp_file();
 | 
			
		||||
  int generate_fragment();
 | 
			
		||||
  int switch_fragment();
 | 
			
		||||
private:
 | 
			
		||||
  ObDirectLoadExternalMultiPartitionTableBuildParam param_;
 | 
			
		||||
  common::ObArenaAllocator allocator_;
 | 
			
		||||
  ObDirectLoadTmpFileHandle file_handle_;
 | 
			
		||||
  ExternalWriter external_writer_;
 | 
			
		||||
  RowType row_;
 | 
			
		||||
  int64_t row_count_;
 | 
			
		||||
  ObDirectLoadExternalFragmentArray fragment_array_;
 | 
			
		||||
  int64_t total_row_count_;
 | 
			
		||||
  int64_t fragment_row_count_;
 | 
			
		||||
  int64_t max_data_block_size_;
 | 
			
		||||
  bool is_closed_;
 | 
			
		||||
  bool is_inited_;
 | 
			
		||||
  DISALLOW_COPY_AND_ASSIGN(ObDirectLoadExternalMultiPartitionTableBuilder);
 | 
			
		||||
 | 
			
		||||
@ -40,9 +40,10 @@ int ObDirectLoadMemLoader::add_table(ObIDirectLoadPartitionTable *table)
 | 
			
		||||
    if (OB_ISNULL(external_table = dynamic_cast<ObDirectLoadExternalTable *>(table))) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("unexpected table", KR(ret), KPC(table));
 | 
			
		||||
    } else if (OB_UNLIKELY(external_table->get_fragments().count() != 1)) {
 | 
			
		||||
    } else if (OB_UNLIKELY(external_table->get_fragments().count() <= 0)) {
 | 
			
		||||
      ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
      LOG_WARN("files handle should only have one handle", KR(ret));
 | 
			
		||||
      LOG_WARN("files handle should have at least one handle",
 | 
			
		||||
          KR(ret), K(external_table->get_fragments().count()));
 | 
			
		||||
    } else if (OB_FAIL(fragments_.push_back(external_table->get_fragments()))) {
 | 
			
		||||
      LOG_WARN("fail to push back", KR(ret));
 | 
			
		||||
    }
 | 
			
		||||
@ -58,7 +59,7 @@ int ObDirectLoadMemLoader::work()
 | 
			
		||||
  ChunkType *chunk = nullptr;
 | 
			
		||||
  RowType row;
 | 
			
		||||
  for (int64_t i = 0; OB_SUCC(ret) && i < fragments_.count(); i++) {
 | 
			
		||||
    const ObDirectLoadExternalFragment &fragment = fragments_.at(i);
 | 
			
		||||
    ObDirectLoadExternalFragment &fragment = fragments_.at(i);
 | 
			
		||||
    ExternalReader external_reader;
 | 
			
		||||
    if (OB_FAIL(external_reader.init(mem_ctx_->table_data_desc_.external_data_block_size_,
 | 
			
		||||
                                     fragment.max_data_block_size_,
 | 
			
		||||
@ -117,6 +118,9 @@ int ObDirectLoadMemLoader::work()
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (OB_SUCC(ret)) {
 | 
			
		||||
      fragment.reset();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user