Skip to content
Permalink
Browse files
Adding direct update/delete to the server and to the partition engine.
Add support for direct update and direct delete requests for spider.
A direct update/delete request handles all qualified rows in a single
operation rather than one row at a time.

Contains Spiral patches:
006_mariadb-10.2.0.direct_update_rows.diff      MDEV-7704
008_mariadb-10.2.0.partition_direct_update.diff MDEV-7706
010_mariadb-10.2.0.direct_update_rows2.diff     MDEV-7708
011_mariadb-10.2.0.aggregate.diff               MDEV-7709
027_mariadb-10.2.0.force_bulk_update.diff       MDEV-7724
061_mariadb-10.2.0.mariadb-10.1.8.diff          MDEV-12870

- The differences compared to the original patches:
  - Most of the parameters of the new functions are unnecessary.  The
    unnecessary parameters have been removed.
  - Changed bit positions for new handler flags upon consideration of
    handler flags not needed by other Spiral patches and handler flags
    merged from MySQL.
  - Added info_push() (Was originally part of bulk access patch)
  - Didn't include code related to handler socket
  - Added HA_CAN_DIRECT_UPDATE_AND_DELETE

Original author: Kentoku SHIBA
First reviewer:  Jacob Mathew
Second reviewer: Michael Widenius
  • Loading branch information
Kentoku authored and montywi committed Dec 3, 2017
1 parent d1e4ece commit e53ef20
Show file tree
Hide file tree
Showing 23 changed files with 1,116 additions and 68 deletions.

Large diffs are not rendered by default.

@@ -296,6 +296,7 @@ class ha_partition :public handler
ha_rows m_bulk_inserted_rows;
/** used for prediction of start_bulk_insert rows */
enum_monotonicity_info m_part_func_monotonicity_info;
part_id_range m_direct_update_part_spec;
bool m_pre_calling;
bool m_pre_call_use_parallel;
/* Keep track of bulk access requests */
@@ -535,8 +536,23 @@ class ha_partition :public handler
number of calls to write_row.
*/
virtual int write_row(uchar * buf);
virtual bool start_bulk_update();
virtual int exec_bulk_update(ha_rows *dup_key_found);
virtual int end_bulk_update();
virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
ha_rows *dup_key_found);
virtual int update_row(const uchar * old_data, const uchar * new_data);
virtual int direct_update_rows_init();
virtual int pre_direct_update_rows_init();
virtual int direct_update_rows(ha_rows *update_rows);
virtual int pre_direct_update_rows();
virtual bool start_bulk_delete();
virtual int end_bulk_delete();
virtual int delete_row(const uchar * buf);
virtual int direct_delete_rows_init();
virtual int pre_direct_delete_rows_init();
virtual int direct_delete_rows(ha_rows *delete_rows);
virtual int pre_direct_delete_rows();
virtual int delete_all_rows(void);
virtual int truncate();
virtual void start_bulk_insert(ha_rows rows, uint flags);
@@ -1306,6 +1322,7 @@ class ha_partition :public handler
virtual const COND *cond_push(const COND *cond);
virtual void cond_pop();
virtual void clear_top_table_fields();
virtual int info_push(uint info_type, void *info);

private:
int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
@@ -4058,7 +4058,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)

int
handler::ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
uint *dup_key_found)
ha_rows *dup_key_found)
{
DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
m_lock_type == F_WRLCK);
@@ -6163,6 +6163,59 @@ int handler::ha_delete_row(const uchar *buf)
}


/**
Execute a direct update request. A direct update request updates all
qualified rows in a single operation, rather than one row at a time.
In a Spider cluster the direct update operation is pushed down to the
child levels of the cluster.
Note that this can't be used in case of statment logging
@param update_rows Number of updated rows.
@retval 0 Success.
@retval != 0 Failure.
*/

int handler::ha_direct_update_rows(ha_rows *update_rows)
{
int error;

MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
mark_trx_read_write();

error = direct_update_rows(update_rows);
MYSQL_UPDATE_ROW_DONE(error);
return error;
}


/**
Execute a direct delete request. A direct delete request deletes all
qualified rows in a single operation, rather than one row at a time.
In a Spider cluster the direct delete operation is pushed down to the
child levels of the cluster.
@param delete_rows Number of deleted rows.
@retval 0 Success.
@retval != 0 Failure.
*/

int handler::ha_direct_delete_rows(ha_rows *delete_rows)
{
int error;
/* Ensure we are not using binlog row */
DBUG_ASSERT(!table->in_use->is_current_stmt_binlog_format_row());

MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
mark_trx_read_write();

error = direct_delete_rows(delete_rows);
MYSQL_DELETE_ROW_DONE(error);
return error;
}


/** @brief
use_hidden_primary_key() is called in case of an update/delete when
@@ -287,6 +287,11 @@ enum enum_alter_inplace_result {
*/
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)

/* The following are used by Spider */
#define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50)
#define HA_CAN_FORCE_BULK_DELETE (1ULL << 51)
#define HA_CAN_DIRECT_UPDATE_AND_DELETE (1ULL << 52)

/* The following is for partition handler */
#define HA_CAN_MULTISTEP_MERGE (1LL << 53)

@@ -442,6 +447,12 @@ static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
#define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
#define HA_CHECK_ALL (~0U)

/* Options for info_push() */
#define INFO_KIND_UPDATE_FIELDS 101
#define INFO_KIND_UPDATE_VALUES 102
#define INFO_KIND_FORCE_LIMIT_BEGIN 103
#define INFO_KIND_FORCE_LIMIT_END 104

enum legacy_db_type
{
/* note these numerical values are fixed and can *not* be changed */
@@ -1420,9 +1431,6 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
#define HTON_NO_PARTITION (1 << 8) //Not partition of these tables
#define HTON_CAN_MULTISTEP_MERGE (1 << 9) //You can merge mearged tables
// Engine needs to access the main connect string in partitions
#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 << 10)

/*
This flag should be set when deciding that the engine does not allow
@@ -1443,6 +1451,10 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
// MySQL compatibility. Unused.
#define HTON_SUPPORTS_FOREIGN_KEYS (1 << 0) //Foreign key constraint supported.

#define HTON_CAN_MERGE (1 <<11) //Merge type table
// Engine needs to access the main connect string in partitions
#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12)

class Ha_trx_info;

struct THD_TRANS
@@ -2718,7 +2730,8 @@ class handler :public Sql_alloc
/** Length of ref (1-8 or the clustered key length) */
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
enum init_stat { NONE=0, INDEX, RND };
init_stat inited, pre_inited;

const COND *pushed_cond;
/**
@@ -2817,7 +2830,7 @@ class handler :public Sql_alloc
key_used_on_scan(MAX_KEY),
active_index(MAX_KEY), keyread(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
ft_handler(0), inited(NONE), pre_inited(NONE),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
tracker(NULL),
pushed_idx_cond(NULL),
@@ -2958,7 +2971,7 @@ class handler :public Sql_alloc
DBUG_RETURN(ret);
}
int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
uint *dup_key_found);
ha_rows *dup_key_found);
int ha_delete_all_rows();
int ha_truncate();
int ha_reset_auto_increment(ulonglong value);
@@ -3156,7 +3169,7 @@ class handler :public Sql_alloc
@retval 0 Success
@retval >0 Error code
*/
virtual int exec_bulk_update(uint *dup_key_found)
virtual int exec_bulk_update(ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -3165,7 +3178,7 @@ class handler :public Sql_alloc
Perform any needed clean-up, no outstanding updates are there at the
moment.
*/
virtual void end_bulk_update() { return; }
virtual int end_bulk_update() { return 0; }
/**
Execute all outstanding deletes and close down the bulk delete.
@@ -3208,6 +3221,48 @@ class handler :public Sql_alloc
{ return 0; }
virtual int pre_rnd_next(bool use_parallel)
{ return 0; }
int ha_pre_rnd_init(bool scan)
{
int result;
DBUG_ENTER("ha_pre_rnd_init");
DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan));
pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND;
DBUG_RETURN(result);
}
int ha_pre_rnd_end()
{
DBUG_ENTER("ha_pre_rnd_end");
DBUG_ASSERT(pre_inited==RND);
pre_inited=NONE;
DBUG_RETURN(pre_rnd_end());
}
virtual int pre_rnd_init(bool scan) { return 0; }
virtual int pre_rnd_end() { return 0; }
virtual int pre_index_init(uint idx, bool sorted) { return 0; }
virtual int pre_index_end() { return 0; }
int ha_pre_index_init(uint idx, bool sorted)
{
int result;
DBUG_ENTER("ha_pre_index_init");
DBUG_ASSERT(pre_inited==NONE);
if (!(result= pre_index_init(idx, sorted)))
pre_inited=INDEX;
DBUG_RETURN(result);
}
int ha_pre_index_end()
{
DBUG_ENTER("ha_pre_index_end");
DBUG_ASSERT(pre_inited==INDEX);
pre_inited=NONE;
DBUG_RETURN(pre_index_end());
}
int ha_pre_index_or_rnd_end()
{
return (pre_inited == INDEX ?
ha_pre_index_end() :
pre_inited == RND ? ha_pre_rnd_end() : 0 );
}

/**
@brief
Positions an index cursor to the index specified in the
@@ -3712,6 +3767,11 @@ class handler :public Sql_alloc
*/
virtual void cond_pop() { return; };

/**
Push metadata for the current operation down to the table handler.
*/
virtual int info_push(uint info_type, void *info) { return 0; };

/**
This function is used to get correlating of a parent (table/column)
and children (table/column). When conditions are pushed down to child
@@ -4162,6 +4222,49 @@ class handler :public Sql_alloc
{
return HA_ERR_WRONG_COMMAND;
}

/* Perform initialization for a direct update request */
public:
int ha_direct_update_rows(ha_rows *update_rows);
virtual int direct_update_rows_init()
{
return HA_ERR_WRONG_COMMAND;
}
private:
virtual int pre_direct_update_rows_init()
{
return HA_ERR_WRONG_COMMAND;
}
virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int pre_direct_update_rows()
{
return HA_ERR_WRONG_COMMAND;
}

/* Perform initialization for a direct delete request */
public:
int ha_direct_delete_rows(ha_rows *delete_rows);
virtual int direct_delete_rows_init()
{
return HA_ERR_WRONG_COMMAND;
}
private:
virtual int pre_direct_delete_rows_init()
{
return HA_ERR_WRONG_COMMAND;
}
virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int pre_direct_delete_rows()
{
return HA_ERR_WRONG_COMMAND;
}

/**
Reset state of file to after 'open'.
This function is called after every statement for all tables used
@@ -4236,7 +4339,7 @@ class handler :public Sql_alloc
@retval 1 Bulk delete not used, normal operation used
*/
virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
uint *dup_key_found)
ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -398,6 +398,8 @@ int opt_sum_query(THD *thd,
const_result= 0;
break;
}
longlong info_limit= 1;
table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
if (!(error= table->file->ha_index_init((uint) ref.key, 1)))
error= (is_max ?
get_index_max_value(table, &ref, range_fl) :
@@ -410,6 +412,7 @@ int opt_sum_query(THD *thd,
error= HA_ERR_KEY_NOT_FOUND;
table->file->ha_end_keyread();
table->file->ha_index_end();
table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL);
if (error)
{
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)

0 comments on commit e53ef20

Please sign in to comment.