Reject drop table if any ddl is running on this table
This commit is contained in:
		
				
					committed by
					
						
						wangzelin.wzl
					
				
			
			
				
	
			
			
			
						parent
						
							44cebeb825
						
					
				
				
					commit
					f83bd7225c
				
			@ -1400,6 +1400,64 @@ int ObDDLTaskRecordOperator::check_has_long_running_ddl(
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObDDLTaskRecordOperator::check_has_conflict_ddl(
 | 
			
		||||
    common::ObMySQLProxy *proxy,
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    const uint64_t table_id,
 | 
			
		||||
    const int64_t task_id,
 | 
			
		||||
    const ObDDLType ddl_type,
 | 
			
		||||
    bool &has_conflict_ddl)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  has_conflict_ddl = false;
 | 
			
		||||
  if (OB_UNLIKELY(nullptr == proxy || !proxy->is_inited() 
 | 
			
		||||
    || OB_INVALID_ID == tenant_id
 | 
			
		||||
    || OB_INVALID_ID == table_id)) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid arg", K(ret), KP(proxy), K(tenant_id), K(table_id));
 | 
			
		||||
  } else {
 | 
			
		||||
    ObSqlString sql_string;
 | 
			
		||||
    SMART_VAR(ObMySQLProxy::MySQLResult, res) {
 | 
			
		||||
      sqlclient::ObMySQLResult *result = nullptr;
 | 
			
		||||
      if (OB_FAIL(sql_string.assign_fmt("SELECT tenant_id, task_id, object_id, target_object_id, ddl_type,"
 | 
			
		||||
          "schema_version, parent_task_id, trace_id, status, snapshot_version, task_version,"
 | 
			
		||||
          "UNHEX(ddl_stmt_str) as ddl_stmt_str_unhex, ret_code, UNHEX(message) as message_unhex FROM %s "
 | 
			
		||||
          "WHERE tenant_id = %lu AND object_id = %lu", OB_ALL_VIRTUAL_DDL_TASK_STATUS_TNAME,
 | 
			
		||||
          tenant_id, table_id))) {
 | 
			
		||||
        LOG_WARN("assign sql string failed", K(ret));
 | 
			
		||||
      } else if (OB_FAIL(proxy->read(res, sql_string.ptr()))) {
 | 
			
		||||
        LOG_WARN("query ddl task record failed", K(ret), K(sql_string));
 | 
			
		||||
      } else if (OB_ISNULL(result = res.get_result())) {
 | 
			
		||||
        ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
        LOG_WARN("fail to get sql result", K(ret), KP(result));
 | 
			
		||||
      } else {
 | 
			
		||||
        ObDDLTaskRecord task_record;
 | 
			
		||||
        ObArenaAllocator allocator("DdlTaskRec");
 | 
			
		||||
        while (OB_SUCC(ret) && !has_conflict_ddl && OB_SUCC(result->next())) {
 | 
			
		||||
          allocator.reuse();
 | 
			
		||||
          if (OB_FAIL(fill_task_record(result, allocator, task_record))) {
 | 
			
		||||
            LOG_WARN("failed to fill task record", K(ret));
 | 
			
		||||
          } else if (task_record.task_id_ != task_id) {
 | 
			
		||||
            switch (ddl_type) {
 | 
			
		||||
            case ObDDLType::DDL_DROP_TABLE: {
 | 
			
		||||
              has_conflict_ddl = true;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
            default: {
 | 
			
		||||
              // do nothing
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (OB_ITER_END == ret) {
 | 
			
		||||
          ret = OB_SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObDDLTaskRecordOperator::get_all_record(
 | 
			
		||||
    common::ObMySQLProxy &proxy,
 | 
			
		||||
    common::ObIAllocator &allocator,
 | 
			
		||||
 | 
			
		||||
@ -153,6 +153,14 @@ public:
 | 
			
		||||
     const uint64_t table_id,
 | 
			
		||||
     bool &has_long_running_ddl);
 | 
			
		||||
 | 
			
		||||
  static int check_has_conflict_ddl(
 | 
			
		||||
      common::ObMySQLProxy *proxy,
 | 
			
		||||
      const uint64_t tenant_id,
 | 
			
		||||
      const uint64_t table_id,
 | 
			
		||||
      const int64_t task_id,
 | 
			
		||||
      const share::ObDDLType ddl_type,
 | 
			
		||||
      bool &has_conflict_ddl);
 | 
			
		||||
 | 
			
		||||
  static int insert_record(
 | 
			
		||||
      common::ObISQLClient &proxy,
 | 
			
		||||
      const ObDDLTaskRecord &record);
 | 
			
		||||
 | 
			
		||||
@ -15351,6 +15351,7 @@ int ObDDLService::modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_tab
 | 
			
		||||
          new_col_schema.set_nullable(false);
 | 
			
		||||
          new_col_schema.drop_not_null_cst();
 | 
			
		||||
          new_hidden_table_schema.set_in_offline_ddl_white_list(true);
 | 
			
		||||
          ObSchemaOperationType operation_type = OB_DDL_ALTER_TABLE;
 | 
			
		||||
          if (OB_FAIL(new_hidden_table_schema.alter_column(new_col_schema, ObTableSchema::CHECK_MODE_ONLINE))) {
 | 
			
		||||
            LOG_WARN("failed to alter column", K(ret));
 | 
			
		||||
          } else if (OB_FAIL(ddl_operator.update_single_column(trans,
 | 
			
		||||
@ -15363,6 +15364,8 @@ int ObDDLService::modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_tab
 | 
			
		||||
                                                                                    new_hidden_table_schema,
 | 
			
		||||
                                                                                    trans))) {
 | 
			
		||||
            LOG_WARN("failed to drop constraint", K(ret));
 | 
			
		||||
          } else if (OB_FAIL(ddl_operator.update_table_attribute(new_hidden_table_schema, trans, operation_type))) {
 | 
			
		||||
            LOG_WARN("failed to update data table schema attribute", K(ret));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -18222,10 +18225,22 @@ int ObDDLService::drop_table(const ObDropTableArg &drop_table_arg, const obrpc::
 | 
			
		||||
              */
 | 
			
		||||
            } else {
 | 
			
		||||
              bool to_recyclebin = drop_table_arg.to_recyclebin_;
 | 
			
		||||
              bool has_conflict_ddl = false;
 | 
			
		||||
              if (table_schema->get_table_type() == MATERIALIZED_VIEW || table_schema->is_tmp_table()) {
 | 
			
		||||
                to_recyclebin = false;
 | 
			
		||||
              }
 | 
			
		||||
              if (OB_FAIL(drop_table_in_trans(schema_guard,
 | 
			
		||||
              if (OB_FAIL(ObDDLTaskRecordOperator::check_has_conflict_ddl(
 | 
			
		||||
                      sql_proxy_,
 | 
			
		||||
                      drop_table_arg.tenant_id_,
 | 
			
		||||
                      table_schema->get_table_id(),
 | 
			
		||||
                      drop_table_arg.task_id_,
 | 
			
		||||
                      ObDDLType::DDL_DROP_TABLE,
 | 
			
		||||
                      has_conflict_ddl))) {
 | 
			
		||||
                LOG_WARN("failed to check has conflict ddl", K(ret));
 | 
			
		||||
              } else if (has_conflict_ddl) {
 | 
			
		||||
                ret = OB_SCHEMA_EAGAIN;
 | 
			
		||||
                LOG_WARN("failed to drop table that has conflict ddl", K(ret), K(table_schema->get_table_id()));
 | 
			
		||||
              } else if (OB_FAIL(drop_table_in_trans(schema_guard,
 | 
			
		||||
                          tmp_table_schema,
 | 
			
		||||
                          false,
 | 
			
		||||
                          USER_INDEX == drop_table_arg.table_type_,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user