You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-4769 Fix cache bugs. (#2151)
* MCOL-4769 Do not replay INSERTs and LDIs on the replica nodes when the write cache is enabled. * MCOL-4769 If a table is created with the write cache disabled (i.e. when columnstore_cache_inserts=OFF), make it accessible when the cache feature is enabled (columnstore_cache_inserts=ON).
This commit is contained in:
@ -1233,6 +1233,9 @@ static void create_cache_name(char *to, const char *name)
|
|||||||
my_bool get_status_and_flush_cache(void *param,
|
my_bool get_status_and_flush_cache(void *param,
|
||||||
my_bool concurrent_insert)
|
my_bool concurrent_insert)
|
||||||
{
|
{
|
||||||
|
if (current_thd->slave_thread && !get_replication_slave(current_thd))
|
||||||
|
return (0);
|
||||||
|
|
||||||
ha_mcs_cache *cache= (ha_mcs_cache*) param;
|
ha_mcs_cache *cache= (ha_mcs_cache*) param;
|
||||||
int error;
|
int error;
|
||||||
enum_sql_command sql_command= cache->table->in_use->lex->sql_command;
|
enum_sql_command sql_command= cache->table->in_use->lex->sql_command;
|
||||||
@ -1398,7 +1401,7 @@ void ha_mcs_cache_share::close()
|
|||||||
static plugin_ref plugin_maria = NULL;
|
static plugin_ref plugin_maria = NULL;
|
||||||
|
|
||||||
ha_mcs_cache::ha_mcs_cache(handlerton *hton, TABLE_SHARE *table_arg, MEM_ROOT *mem_root)
|
ha_mcs_cache::ha_mcs_cache(handlerton *hton, TABLE_SHARE *table_arg, MEM_ROOT *mem_root)
|
||||||
:ha_mcs(mcs_hton, table_arg), isSysCatTable(false)
|
:ha_mcs(mcs_hton, table_arg), isSysCatTable(false), isCacheDisabled(false)
|
||||||
{
|
{
|
||||||
if (table_arg && table_arg->db.str &&
|
if (table_arg && table_arg->db.str &&
|
||||||
!strcasecmp(table_arg->db.str, "calpontsys") &&
|
!strcasecmp(table_arg->db.str, "calpontsys") &&
|
||||||
@ -1451,21 +1454,19 @@ int ha_mcs_cache::create(const char *name, TABLE *table_arg,
|
|||||||
char cache_name[FN_REFLEN+8];
|
char cache_name[FN_REFLEN+8];
|
||||||
DBUG_ENTER("ha_mcs_cache::create");
|
DBUG_ENTER("ha_mcs_cache::create");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
create_cache_name(cache_name, name);
|
create_cache_name(cache_name, name);
|
||||||
{
|
/* Create a cached table */
|
||||||
/* Create a cached table */
|
ha_choice save_transactional= ha_create_info->transactional;
|
||||||
ha_choice save_transactional= ha_create_info->transactional;
|
row_type save_row_type= ha_create_info->row_type;
|
||||||
row_type save_row_type= ha_create_info->row_type;
|
ha_create_info->transactional= HA_CHOICE_NO;
|
||||||
ha_create_info->transactional= HA_CHOICE_NO;
|
ha_create_info->row_type= ROW_TYPE_DYNAMIC;
|
||||||
ha_create_info->row_type= ROW_TYPE_DYNAMIC;
|
|
||||||
|
|
||||||
if ((error= cache_handler->create(cache_name, table_arg, ha_create_info)))
|
if ((error= cache_handler->create(cache_name, table_arg, ha_create_info)))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
ha_create_info->transactional= save_transactional;
|
ha_create_info->transactional= save_transactional;
|
||||||
ha_create_info->row_type= save_row_type;
|
ha_create_info->row_type= save_row_type;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the real table in ColumnStore */
|
/* Create the real table in ColumnStore */
|
||||||
@ -1482,7 +1483,7 @@ int ha_mcs_cache::create(const char *name, TABLE *table_arg,
|
|||||||
|
|
||||||
int ha_mcs_cache::open(const char *name, int mode, uint open_flags)
|
int ha_mcs_cache::open(const char *name, int mode, uint open_flags)
|
||||||
{
|
{
|
||||||
int error;
|
int error, cache_error;
|
||||||
DBUG_ENTER("ha_mcs_cache::open");
|
DBUG_ENTER("ha_mcs_cache::open");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
||||||
@ -1492,46 +1493,63 @@ int ha_mcs_cache::open(const char *name, int mode, uint open_flags)
|
|||||||
|
|
||||||
char cache_name[FN_REFLEN+8];
|
char cache_name[FN_REFLEN+8];
|
||||||
create_cache_name(cache_name, name);
|
create_cache_name(cache_name, name);
|
||||||
if ((error= cache_handler->open(cache_name, mode, open_flags)))
|
|
||||||
DBUG_RETURN(error);
|
|
||||||
|
|
||||||
if (!(share= find_cache_share(name, cache_handler->file->state->records)))
|
if (!(cache_error= cache_handler->open(cache_name, mode, open_flags)))
|
||||||
{
|
{
|
||||||
cache_handler->close();
|
if (!(share= find_cache_share(name, cache_handler->file->state->records)))
|
||||||
DBUG_RETURN(ER_OUTOFMEMORY);
|
{
|
||||||
}
|
cache_handler->close();
|
||||||
|
DBUG_RETURN(ER_OUTOFMEMORY);
|
||||||
/* Fix lock so that it goes through get_status_and_flush() */
|
}
|
||||||
THR_LOCK *lock= &cache_handler->file->s->lock;
|
|
||||||
if (lock->get_status != &get_status_and_flush_cache)
|
|
||||||
{
|
|
||||||
mysql_mutex_lock(&cache_handler->file->s->intern_lock);
|
|
||||||
|
|
||||||
/* The following lock is here just to establish mutex locking order */
|
|
||||||
mysql_mutex_lock(&lock->mutex);
|
|
||||||
mysql_mutex_unlock(&lock->mutex);
|
|
||||||
|
|
||||||
|
/* Fix lock so that it goes through get_status_and_flush() */
|
||||||
|
THR_LOCK *lock= &cache_handler->file->s->lock;
|
||||||
if (lock->get_status != &get_status_and_flush_cache)
|
if (lock->get_status != &get_status_and_flush_cache)
|
||||||
{
|
{
|
||||||
/* Remember original lock. Used by the THR_lock cache functions */
|
mysql_mutex_lock(&cache_handler->file->s->intern_lock);
|
||||||
share->org_lock= lock[0];
|
|
||||||
if (lock->start_trans)
|
/* The following lock is here just to establish mutex locking order */
|
||||||
lock->start_trans= &cache_start_trans;
|
mysql_mutex_lock(&lock->mutex);
|
||||||
if (lock->copy_status)
|
mysql_mutex_unlock(&lock->mutex);
|
||||||
lock->copy_status= &cache_copy_status;
|
|
||||||
if (lock->update_status)
|
if (lock->get_status != &get_status_and_flush_cache)
|
||||||
lock->update_status= &cache_update_status;
|
{
|
||||||
if (lock->restore_status)
|
/* Remember original lock. Used by the THR_lock cache functions */
|
||||||
lock->restore_status= &cache_restore_status;
|
share->org_lock= lock[0];
|
||||||
if (lock->check_status)
|
if (lock->start_trans)
|
||||||
lock->check_status= &cache_check_status;
|
lock->start_trans= &cache_start_trans;
|
||||||
if (lock->restore_status)
|
if (lock->copy_status)
|
||||||
lock->restore_status= &cache_restore_status;
|
lock->copy_status= &cache_copy_status;
|
||||||
lock->get_status= &get_status_and_flush_cache;
|
if (lock->update_status)
|
||||||
|
lock->update_status= &cache_update_status;
|
||||||
|
if (lock->restore_status)
|
||||||
|
lock->restore_status= &cache_restore_status;
|
||||||
|
if (lock->check_status)
|
||||||
|
lock->check_status= &cache_check_status;
|
||||||
|
if (lock->restore_status)
|
||||||
|
lock->restore_status= &cache_restore_status;
|
||||||
|
lock->get_status= &get_status_and_flush_cache;
|
||||||
|
}
|
||||||
|
mysql_mutex_unlock(&cache_handler->file->s->intern_lock);
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&cache_handler->file->s->intern_lock);
|
cache_handler->file->lock.status_param= (void*) this;
|
||||||
|
}
|
||||||
|
else if (cache_error == ENOENT)
|
||||||
|
{
|
||||||
|
if (!(error= parent::open(name, mode, open_flags)))
|
||||||
|
{
|
||||||
|
isCacheDisabled = true;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_RETURN(cache_error);
|
||||||
}
|
}
|
||||||
cache_handler->file->lock.status_param= (void*) this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error= parent::open(name, mode, open_flags)))
|
if ((error= parent::open(name, mode, open_flags)))
|
||||||
@ -1551,7 +1569,7 @@ int ha_mcs_cache::close()
|
|||||||
|
|
||||||
DBUG_ENTER("ha_mcs_cache::close()");
|
DBUG_ENTER("ha_mcs_cache::close()");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
error= cache_handler->close();
|
error= cache_handler->close();
|
||||||
if ((error2= parent::close()))
|
if ((error2= parent::close()))
|
||||||
@ -1580,7 +1598,7 @@ uint ha_mcs_cache::lock_count(void) const
|
|||||||
If we are doing an insert or if we want to flush the cache, we have to lock
|
If we are doing an insert or if we want to flush the cache, we have to lock
|
||||||
both the Aria table and normal table.
|
both the Aria table and normal table.
|
||||||
*/
|
*/
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
return 2;
|
return 2;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
@ -1594,7 +1612,7 @@ THR_LOCK_DATA **ha_mcs_cache::store_lock(THD *thd,
|
|||||||
THR_LOCK_DATA **to,
|
THR_LOCK_DATA **to,
|
||||||
enum thr_lock_type lock_type)
|
enum thr_lock_type lock_type)
|
||||||
{
|
{
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
to= cache_handler->store_lock(thd, to, TL_WRITE);
|
to= cache_handler->store_lock(thd, to, TL_WRITE);
|
||||||
return parent::store_lock(thd, to, lock_type);
|
return parent::store_lock(thd, to, lock_type);
|
||||||
}
|
}
|
||||||
@ -1609,7 +1627,7 @@ int ha_mcs_cache::external_lock(THD *thd, int lock_type)
|
|||||||
int error= 0;
|
int error= 0;
|
||||||
DBUG_ENTER("ha_mcs_cache::external_lock");
|
DBUG_ENTER("ha_mcs_cache::external_lock");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Reset lock_counter. This is ok as external_lock() is guaranteed to be
|
Reset lock_counter. This is ok as external_lock() is guaranteed to be
|
||||||
@ -1659,7 +1677,7 @@ int ha_mcs_cache::delete_table(const char *name)
|
|||||||
|
|
||||||
DBUG_ENTER("ha_mcs_cache::delete_table");
|
DBUG_ENTER("ha_mcs_cache::delete_table");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
char cache_name[FN_REFLEN+8];
|
char cache_name[FN_REFLEN+8];
|
||||||
create_cache_name(cache_name, name);
|
create_cache_name(cache_name, name);
|
||||||
@ -1679,18 +1697,25 @@ int ha_mcs_cache::rename_table(const char *from, const char *to)
|
|||||||
|
|
||||||
DBUG_ENTER("ha_mcs_cache::rename_table");
|
DBUG_ENTER("ha_mcs_cache::rename_table");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
char cache_from[FN_REFLEN+8], cache_to[FN_REFLEN+8];
|
char cache_from[FN_REFLEN+8], cache_to[FN_REFLEN+8];
|
||||||
create_cache_name(cache_from, from);
|
create_cache_name(cache_from, from);
|
||||||
create_cache_name(cache_to, to);
|
create_cache_name(cache_to, to);
|
||||||
if ((error= cache_handler->rename_table(cache_from, cache_to)))
|
if (!(error= cache_handler->rename_table(cache_from, cache_to)))
|
||||||
DBUG_RETURN(error);
|
|
||||||
|
|
||||||
if ((error= parent::rename_table(from, to)))
|
|
||||||
{
|
{
|
||||||
cache_handler->rename_table(cache_to, cache_from);
|
if ((error= parent::rename_table(from, to)))
|
||||||
DBUG_RETURN(error);
|
{
|
||||||
|
cache_handler->rename_table(cache_to, cache_from);
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (error == ENOENT)
|
||||||
|
{
|
||||||
|
if ((error= parent::rename_table(from, to)))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1708,7 +1733,7 @@ int ha_mcs_cache::delete_all_rows(void)
|
|||||||
|
|
||||||
DBUG_ENTER("ha_mcs_cache::delete_all_rows");
|
DBUG_ENTER("ha_mcs_cache::delete_all_rows");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
error= cache_handler->delete_all_rows();
|
error= cache_handler->delete_all_rows();
|
||||||
share->cached_rows= 0;
|
share->cached_rows= 0;
|
||||||
@ -1720,7 +1745,7 @@ int ha_mcs_cache::delete_all_rows(void)
|
|||||||
|
|
||||||
bool ha_mcs_cache::is_crashed() const
|
bool ha_mcs_cache::is_crashed() const
|
||||||
{
|
{
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
return (cache_handler->is_crashed() ||
|
return (cache_handler->is_crashed() ||
|
||||||
parent::is_crashed());
|
parent::is_crashed());
|
||||||
else
|
else
|
||||||
@ -1752,7 +1777,7 @@ int ha_mcs_cache::repair(THD *thd, HA_CHECK_OPT *check_opt)
|
|||||||
int something_crashed= is_crashed();
|
int something_crashed= is_crashed();
|
||||||
DBUG_ENTER("ha_mcs_cache::repair");
|
DBUG_ENTER("ha_mcs_cache::repair");
|
||||||
|
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
if (cache_handler->is_crashed() || !something_crashed)
|
if (cache_handler->is_crashed() || !something_crashed)
|
||||||
{
|
{
|
||||||
@ -1782,19 +1807,26 @@ int ha_mcs_cache::repair(THD *thd, HA_CHECK_OPT *check_opt)
|
|||||||
*/
|
*/
|
||||||
int ha_mcs_cache::write_row(const uchar *buf)
|
int ha_mcs_cache::write_row(const uchar *buf)
|
||||||
{
|
{
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable && insert_command)
|
if (current_thd->slave_thread && !get_replication_slave(current_thd))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (isCacheEnabled() && insert_command)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(share->cached_rows == cache_handler->file->state->records);
|
DBUG_ASSERT(share->cached_rows == cache_handler->file->state->records);
|
||||||
share->cached_rows++;
|
share->cached_rows++;
|
||||||
return cache_handler->write_row(buf);
|
return cache_handler->write_row(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::write_row(buf);
|
return parent::write_row(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ha_mcs_cache::start_bulk_insert(ha_rows rows, uint flags)
|
void ha_mcs_cache::start_bulk_insert(ha_rows rows, uint flags)
|
||||||
{
|
{
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable)
|
if (current_thd->slave_thread && !get_replication_slave(current_thd))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isCacheEnabled())
|
||||||
{
|
{
|
||||||
if (insert_command)
|
if (insert_command)
|
||||||
{
|
{
|
||||||
@ -1821,7 +1853,10 @@ void ha_mcs_cache::start_bulk_insert(ha_rows rows, uint flags)
|
|||||||
|
|
||||||
int ha_mcs_cache::end_bulk_insert()
|
int ha_mcs_cache::end_bulk_insert()
|
||||||
{
|
{
|
||||||
if (get_cache_inserts(current_thd) && !isSysCatTable && insert_command)
|
if (current_thd->slave_thread && !get_replication_slave(current_thd))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (isCacheEnabled() && insert_command)
|
||||||
return cache_handler->end_bulk_insert();
|
return cache_handler->end_bulk_insert();
|
||||||
return parent::end_bulk_insert();
|
return parent::end_bulk_insert();
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,16 @@ class ha_mcs_cache :public ha_mcs
|
|||||||
// calpontsys.syscolumn system catalog tables
|
// calpontsys.syscolumn system catalog tables
|
||||||
bool isSysCatTable;
|
bool isSysCatTable;
|
||||||
|
|
||||||
|
// True if the ColumnStore table is not cached (i.e. when the table
|
||||||
|
// was created with columnstore_cache_inserts=OFF).
|
||||||
|
bool isCacheDisabled;
|
||||||
|
|
||||||
|
bool isCacheEnabled() const
|
||||||
|
{
|
||||||
|
return (get_cache_inserts(current_thd) && !isSysCatTable &&
|
||||||
|
!isCacheDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint lock_counter;
|
uint lock_counter;
|
||||||
ha_maria *cache_handler;
|
ha_maria *cache_handler;
|
||||||
|
Reference in New Issue
Block a user