Skip to content
Permalink
Browse files
MDEV-16246: insert timestamp into spider table from mysqldump gets wr…
…ong time zone.

The problem occurred because the Spider node was incorrectly handling
timestamp values sent to and received from the data nodes.

The problem has been corrected as follows:
- Added logic to set and maintain the UTC time zone on the data nodes.
  To prevent timestamp ambiguity, it is necessary for the data nodes to use
  a time zone such as UTC which does not have daylight savings time.
- Removed the spider_sync_time_zone configuration variable, which did not
  solve the problem and which interfered with the solution.
- Added logic to convert to the UTC time zone all timestamp values sent to
  and received from the data nodes.  This is done for both unique and
  non-unique timestamp columns.  It is done for WHERE clauses, applying to
  SELECT, UPDATE and DELETE statements, and for UPDATE columns.
- Disabled Spider's use of direct update when any of the columns to update is
  a timestamp column.  This is necessary to prevent false duplicate key value
  errors.
- Added a new test spider.timestamp to thoroughly test Spider's handling of
  timestamp values.

Author:
  Jacob Mathew.

Reviewer:
  Kentoku Shiba.

Cherry-Picked:
  Commit 97cc9d3 on branch bb-10.3-MDEV-16246
  • Loading branch information
Jacob Mathew committed Jul 9, 2018
1 parent bbf780e commit 813b739
Show file tree
Hide file tree
Showing 23 changed files with 1,575 additions and 284 deletions.
@@ -11143,13 +11143,14 @@ int ha_partition::end_bulk_delete()
SYNOPSIS
direct_update_rows_init()
update fields Pointer to the list of fields to update
RETURN VALUE
>0 Error
0 Success
*/

int ha_partition::direct_update_rows_init()
int ha_partition::direct_update_rows_init(List<Item> *update_fields)
{
int error;
uint i, found;
@@ -11175,8 +11176,8 @@ int ha_partition::direct_update_rows_init()
{
file= m_file[i];
if (unlikely((error= (m_pre_calling ?
file->pre_direct_update_rows_init() :
file->direct_update_rows_init()))))
file->pre_direct_update_rows_init(update_fields) :
file->direct_update_rows_init(update_fields)))))
{
DBUG_PRINT("info", ("partition FALSE by storage engine"));
DBUG_RETURN(error);
@@ -11214,20 +11215,21 @@ int ha_partition::direct_update_rows_init()
SYNOPSIS
pre_direct_update_rows_init()
update fields Pointer to the list of fields to update
RETURN VALUE
>0 Error
0 Success
*/

int ha_partition::pre_direct_update_rows_init()
int ha_partition::pre_direct_update_rows_init(List<Item> *update_fields)
{
bool save_m_pre_calling;
int error;
DBUG_ENTER("ha_partition::pre_direct_update_rows_init");
save_m_pre_calling= m_pre_calling;
m_pre_calling= TRUE;
error= direct_update_rows_init();
error= direct_update_rows_init(update_fields);
m_pre_calling= save_m_pre_calling;
DBUG_RETURN(error);
}
@@ -620,8 +620,8 @@ class ha_partition :public handler
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_init(List<Item> *update_fields);
virtual int pre_direct_update_rows_init(List<Item> *update_fields);
virtual int direct_update_rows(ha_rows *update_rows);
virtual int pre_direct_update_rows();
virtual bool start_bulk_delete();
@@ -4407,12 +4407,12 @@ class handler :public Sql_alloc
/* Perform initialization for a direct update request */
public:
int ha_direct_update_rows(ha_rows *update_rows);
virtual int direct_update_rows_init()
virtual int direct_update_rows_init(List<Item> *update_fields)
{
return HA_ERR_WRONG_COMMAND;
}
private:
virtual int pre_direct_update_rows_init()
virtual int pre_direct_update_rows_init(List<Item> *update_fields)
{
return HA_ERR_WRONG_COMMAND;
}
@@ -615,6 +615,9 @@ int mysql_update(THD *thd,
- Note that Spider can handle ORDER BY and LIMIT in a cluster with
one data node. These conditions are therefore checked in
direct_update_rows_init().
- Update fields include a unique timestamp field
- The storage engine may not be able to avoid false duplicate key
errors. This condition is checked in direct_update_rows_init().
Direct update does not require a WHERE clause
@@ -637,7 +640,7 @@ int mysql_update(THD *thd,

if (!table->file->info_push(INFO_KIND_UPDATE_FIELDS, &fields) &&
!table->file->info_push(INFO_KIND_UPDATE_VALUES, &values) &&
!table->file->direct_update_rows_init())
!table->file->direct_update_rows_init(&fields))
{
do_direct_update= TRUE;

@@ -10064,13 +10064,11 @@ int ha_spider::update_row(

#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
const uchar *new_data
) {
int ha_spider::direct_update_rows_init(List<Item> *update_fields, uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count, bool sorted,
const uchar *new_data)
{
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
int error_num;
#endif
@@ -10098,7 +10096,7 @@ int ha_spider::direct_update_rows_init(
DBUG_RETURN(pre_direct_init_result);
}
DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_update_rows_init(
mode, ranges, range_count, sorted, new_data));
update_fields, mode, ranges, range_count, sorted, new_data));
}
#endif
direct_update_init(
@@ -10202,14 +10200,46 @@ int ha_spider::direct_update_rows_init(
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
#else
int ha_spider::direct_update_rows_init()
/**
Perform initialization for a direct update request.

@param update fields Pointer to the list of fields to update.

@return >0 Error.
0 Success.
*/

int ha_spider::direct_update_rows_init(List<Item> *update_fields)
{
st_select_lex *select_lex;
longlong select_limit;
longlong offset_limit;
List_iterator<Item> it(*update_fields);
Item *item;
Field *field;
THD *thd = trx->thd;
DBUG_ENTER("ha_spider::direct_update_rows_init");
DBUG_PRINT("info",("spider this=%p", this));

while ((item = it++))
{
if (item->type() == Item::FIELD_ITEM)
{
field = ((Item_field *)item)->field;

if (field->type() == FIELD_TYPE_TIMESTAMP &&
field->flags & UNIQUE_KEY_FLAG)
{
/*
Spider cannot perform direct update on unique timestamp fields.
To avoid false duplicate key errors, the table needs to be
updated one row at a time.
*/
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
}
}

#ifdef HA_CAN_BULK_ACCESS
if (
bulk_access_executing &&
@@ -10227,7 +10257,8 @@ int ha_spider::direct_update_rows_init()
pre_direct_init_result));
DBUG_RETURN(pre_direct_init_result);
}
DBUG_RETURN(bulk_access_link_exec_tgt->spider->direct_update_rows_init());
DBUG_RETURN(bulk_access_link_exec_tgt->spider->
direct_update_rows_init(List<Item> *update_fields));
}
#endif
direct_update_init(
@@ -10298,44 +10329,54 @@ int ha_spider::direct_update_rows_init()

#ifdef HA_CAN_BULK_ACCESS
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
int ha_spider::pre_direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
const uchar *new_data
) {
int ha_spider::pre_direct_update_rows_init(List<Item> *update_fields,
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count, bool sorted,
const uchar *new_data)
{
int error_num;
DBUG_ENTER("ha_spider::pre_direct_update_rows_init");
DBUG_PRINT("info",("spider this=%p", this));
if (bulk_access_started)
{
error_num = bulk_access_link_current->spider->
pre_direct_update_rows_init(
mode, ranges, range_count, sorted, new_data);
pre_direct_update_rows_init(update_fields, mode, ranges, range_count,
sorted, new_data);
bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
bulk_access_link_current->called = TRUE;
DBUG_RETURN(error_num);
}
pre_direct_init_result = direct_update_rows_init(
mode, ranges, range_count, sorted, new_data);
pre_direct_init_result = direct_update_rows_init(update_fields, mode,
ranges, range_count,
sorted, new_data);
DBUG_RETURN(pre_direct_init_result);
}
#else
int ha_spider::pre_direct_update_rows_init()
/**
Do initialization for performing parallel direct update
for a handlersocket update request.

@param update fields Pointer to the list of fields to update.

@return >0 Error.
0 Success.
*/

int ha_spider::pre_direct_update_rows_init(List<Item> *update_fields)
{
int error_num;
DBUG_ENTER("ha_spider::pre_direct_update_rows_init");
DBUG_PRINT("info",("spider this=%p", this));
if (bulk_access_started)
{
error_num = bulk_access_link_current->spider->
pre_direct_update_rows_init();
pre_direct_update_rows_init(update_fields);
bulk_access_link_current->spider->bulk_access_pre_called = TRUE;
bulk_access_link_current->called = TRUE;
DBUG_RETURN(error_num);
}
pre_direct_init_result = direct_update_rows_init();
pre_direct_init_result = direct_update_rows_init(update_fields);
DBUG_RETURN(pre_direct_init_result);
}
#endif
@@ -15733,8 +15774,9 @@ int ha_spider::print_item_type(
dbton_hdl = dbton_handler[dbton_id];
if (
dbton_hdl->first_link_idx >= 0 &&
(error_num = spider_db_print_item_type(item, this, str,
alias, alias_length, dbton_id, FALSE, NULL))
(error_num = spider_db_print_item_type(item, NULL, this, str,
alias, alias_length, dbton_id,
FALSE, NULL))
) {
DBUG_RETURN(error_num);
}
@@ -587,35 +587,29 @@ class ha_spider: public handler
);
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
inline int direct_update_rows_init()
inline int direct_update_rows_init(List<Item> *update_fields)
{
return direct_update_rows_init(2, NULL, 0, FALSE, NULL);
return direct_update_rows_init(update_fields, 2, NULL, 0, FALSE, NULL);
}
int direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
const uchar *new_data
);
int direct_update_rows_init(List<Item> *update_fields, uint mode,
KEY_MULTI_RANGE *ranges, uint range_count,
bool sorted, const uchar *new_data);
#else
int direct_update_rows_init();
int direct_update_rows_init(List<Item> *update_fields);
#endif
#ifdef HA_CAN_BULK_ACCESS
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS
inline int pre_direct_update_rows_init()
inline int pre_direct_update_rows_init(List<Item> *update_fields)
{
return pre_direct_update_rows_init(2, NULL, 0, FALSE, NULL);
return pre_direct_update_rows_init(update_fields,
2, NULL, 0, FALSE, NULL);
}
int pre_direct_update_rows_init(
uint mode,
KEY_MULTI_RANGE *ranges,
uint range_count,
bool sorted,
uchar *new_data
);
int pre_direct_update_rows_init(List<Item> *update_fields,
uint mode, KEY_MULTI_RANGE *ranges,
uint range_count, bool sorted,
uchar *new_data);
#else
int pre_direct_update_rows_init();
int pre_direct_update_rows_init(List<Item> *update_fields);
#endif
#endif
#ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS_WITH_HS

0 comments on commit 813b739

Please sign in to comment.