1
0
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:
Gagan Goel
2021-11-22 15:20:50 -05:00
committed by GitHub
parent 3c65499820
commit affb2ae770
2 changed files with 110 additions and 65 deletions

View File

@ -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();
} }

View File

@ -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;