[BUG] fix nullptr duplicated row for statement-level conflict
This commit is contained in:
		@ -2798,6 +2798,26 @@ int ObLSTabletService::direct_insert_rows(
 | 
				
			|||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ObLSTabletService::mock_duplicated_rows_(common::ObNewRowIterator *&duplicated_rows)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
 | 
					  ObValueRowIterator *dup_iter = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (OB_ISNULL(dup_iter = ObQueryIteratorFactory::get_insert_dup_iter())) {
 | 
				
			||||||
 | 
					    ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
				
			||||||
 | 
					    LOG_WARN("no memory to alloc ObValueRowIterator", K(ret));
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    duplicated_rows = dup_iter;
 | 
				
			||||||
 | 
					    if (OB_FAIL(dup_iter->init(true))) {
 | 
				
			||||||
 | 
					      LOG_WARN("failed to initialize ObValueRowIterator", K(ret));
 | 
				
			||||||
 | 
					      ObQueryIteratorFactory::free_insert_dup_iter(duplicated_rows);
 | 
				
			||||||
 | 
					      duplicated_rows = nullptr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ObLSTabletService::insert_row(
 | 
					int ObLSTabletService::insert_row(
 | 
				
			||||||
    ObTabletHandle &tablet_handle,
 | 
					    ObTabletHandle &tablet_handle,
 | 
				
			||||||
    ObStoreCtx &ctx,
 | 
					    ObStoreCtx &ctx,
 | 
				
			||||||
@ -2845,12 +2865,35 @@ int ObLSTabletService::insert_row(
 | 
				
			|||||||
                                    duplicated_column_ids,
 | 
					                                    duplicated_column_ids,
 | 
				
			||||||
                                    tbl_row.row_val_,
 | 
					                                    tbl_row.row_val_,
 | 
				
			||||||
                                    duplicated_rows))) {
 | 
					                                    duplicated_rows))) {
 | 
				
			||||||
      LOG_WARN("failed to get conflict row(s)", K(ret), K(duplicated_column_ids), K(row));
 | 
					        LOG_WARN("failed to get conflict row(s)", K(ret), K(duplicated_column_ids), K(row));
 | 
				
			||||||
      } else if (nullptr == duplicated_rows) {
 | 
					      } else if (nullptr == duplicated_rows) {
 | 
				
			||||||
        if (OB_FAIL(insert_row_to_tablet(tablet_handle, run_ctx, tbl_row))) {
 | 
					        if (OB_FAIL(insert_row_to_tablet(tablet_handle, run_ctx, tbl_row))) {
 | 
				
			||||||
          if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
 | 
					          if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
 | 
				
			||||||
            LOG_WARN("failed to write row", K(ret));
 | 
					            LOG_WARN("failed to write row", K(ret));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) {
 | 
				
			||||||
 | 
					            int tmp_ret = OB_SUCCESS;
 | 
				
			||||||
 | 
					            // For primary key conflicts caused by concurrent insertions within
 | 
				
			||||||
 | 
					            // a statement, we need to return the corresponding duplicated_rows.
 | 
				
			||||||
 | 
					            // However, under circumstances where an exception may unexpectedly
 | 
				
			||||||
 | 
					            // prevent us from reading the conflicting rows within statements,
 | 
				
			||||||
 | 
					            // at such times, it becomes necessary for us to mock the rows.
 | 
				
			||||||
 | 
					            if (OB_TMP_FAIL(get_conflict_rows(tablet_handle,
 | 
				
			||||||
 | 
					                                              run_ctx,
 | 
				
			||||||
 | 
					                                              flag,
 | 
				
			||||||
 | 
					                                              duplicated_column_ids,
 | 
				
			||||||
 | 
					                                              tbl_row.row_val_,
 | 
				
			||||||
 | 
					                                              duplicated_rows))) {
 | 
				
			||||||
 | 
					              LOG_WARN("failed to get conflict row(s)", K(ret), K(duplicated_column_ids), K(row));
 | 
				
			||||||
 | 
					              ret = tmp_ret;
 | 
				
			||||||
 | 
					            } else if (nullptr == duplicated_rows) {
 | 
				
			||||||
 | 
					              if (OB_TMP_FAIL(mock_duplicated_rows_(duplicated_rows))) {
 | 
				
			||||||
 | 
					                LOG_WARN("failed to mock duplicated row(s)", K(ret), K(duplicated_column_ids), K(row));
 | 
				
			||||||
 | 
					                ret = tmp_ret;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          LOG_DEBUG("succeeded to insert row", K(ret), K(row));
 | 
					          LOG_DEBUG("succeeded to insert row", K(ret), K(row));
 | 
				
			||||||
          affected_rows = 1;
 | 
					          affected_rows = 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -563,6 +563,7 @@ private:
 | 
				
			|||||||
  int offline_build_tablet_without_memtable_();
 | 
					  int offline_build_tablet_without_memtable_();
 | 
				
			||||||
  int offline_gc_tablet_for_create_or_transfer_in_abort_();
 | 
					  int offline_gc_tablet_for_create_or_transfer_in_abort_();
 | 
				
			||||||
  int offline_destroy_memtable_and_mds_table_();
 | 
					  int offline_destroy_memtable_and_mds_table_();
 | 
				
			||||||
 | 
					  int mock_duplicated_rows_(common::ObNewRowIterator *&duplicated_rows);
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  static int check_real_leader_for_4377_(const ObLSID ls_id);
 | 
					  static int check_real_leader_for_4377_(const ObLSID ls_id);
 | 
				
			||||||
  static int check_need_rollback_in_transfer_for_4377_(const transaction::ObTxDesc *tx_desc,
 | 
					  static int check_need_rollback_in_transfer_for_4377_(const transaction::ObTxDesc *tx_desc,
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user