MDEV-29748 ASAN errors or server crash in File_parser::parse upon concurrent view operations
Read the version of the view share when we read definition to prevent simultaniouse access to a view table SHARE (and so its MEM_ROOT) from different threads.
This commit is contained in:
parent
e00ea301ef
commit
4fd6dd2d3b
@ -1175,19 +1175,26 @@ err:
|
|||||||
bool mariadb_view_version_get(TABLE_SHARE *share)
|
bool mariadb_view_version_get(TABLE_SHARE *share)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(share->is_view);
|
DBUG_ASSERT(share->is_view);
|
||||||
|
DBUG_ASSERT(share->tabledef_version.length == 0);
|
||||||
|
|
||||||
if (!(share->tabledef_version.str=
|
if (!(share->tabledef_version.str=
|
||||||
(uchar*) alloc_root(&share->mem_root,
|
(uchar*) alloc_root(&share->mem_root,
|
||||||
MICROSECOND_TIMESTAMP_BUFFER_SIZE)))
|
MICROSECOND_TIMESTAMP_BUFFER_SIZE)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
share->tabledef_version.length= 0; // safety if the drfinition file is brocken
|
|
||||||
|
|
||||||
DBUG_ASSERT(share->view_def != NULL);
|
DBUG_ASSERT(share->view_def != NULL);
|
||||||
if (share->view_def->parse((uchar *) &share->tabledef_version, NULL,
|
if (share->view_def->parse((uchar *) &share->tabledef_version, NULL,
|
||||||
view_timestamp_parameters, 1,
|
view_timestamp_parameters, 1,
|
||||||
&file_parser_dummy_hook))
|
&file_parser_dummy_hook))
|
||||||
|
{
|
||||||
|
// safety if the definition file is brocken
|
||||||
|
share->tabledef_version.length= 0;
|
||||||
|
my_error(ER_TABLE_CORRUPT, MYF(0),
|
||||||
|
share->db.str, share->table_name.str);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
DBUG_ASSERT(share->tabledef_version.length == MICROSECOND_TIMESTAMP_BUFFER_SIZE-1);
|
DBUG_ASSERT(share->tabledef_version.length == MICROSECOND_TIMESTAMP_BUFFER_SIZE-1);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1251,10 +1258,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
|
|||||||
mysql_derived_reinit(thd, NULL, table);
|
mysql_derived_reinit(thd, NULL, table);
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "after_cached_view_opened");
|
DEBUG_SYNC(thd, "after_cached_view_opened");
|
||||||
if (!share->tabledef_version.length)
|
DBUG_ASSERT(share->tabledef_version.length);
|
||||||
{
|
|
||||||
mariadb_view_version_get(share);
|
|
||||||
}
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1308,15 +1312,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
|
|||||||
required_view_parameters,
|
required_view_parameters,
|
||||||
&file_parser_dummy_hook)))
|
&file_parser_dummy_hook)))
|
||||||
goto end;
|
goto end;
|
||||||
if (!share->tabledef_version.length)
|
DBUG_ASSERT(share->tabledef_version.length);
|
||||||
{
|
|
||||||
share->tabledef_version.str= (const uchar *)
|
|
||||||
memdup_root(&share->mem_root,
|
|
||||||
(const void *)
|
|
||||||
table->hr_timestamp.str,
|
|
||||||
(share->tabledef_version.length=
|
|
||||||
table->hr_timestamp.length));
|
|
||||||
}
|
|
||||||
if (!table->tabledef_version.length)
|
if (!table->tabledef_version.length)
|
||||||
{
|
{
|
||||||
table->set_view_def_version(&table->hr_timestamp);
|
table->set_view_def_version(&table->hr_timestamp);
|
||||||
|
@ -64,4 +64,6 @@ extern const LEX_CSTRING view_type;
|
|||||||
|
|
||||||
void make_valid_column_names(List<Item> &item_list);
|
void make_valid_column_names(List<Item> &item_list);
|
||||||
|
|
||||||
|
bool mariadb_view_version_get(TABLE_SHARE *share);
|
||||||
|
|
||||||
#endif /* SQL_VIEW_INCLUDED */
|
#endif /* SQL_VIEW_INCLUDED */
|
||||||
|
@ -633,7 +633,11 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
|
|||||||
if (!share->view_def)
|
if (!share->view_def)
|
||||||
share->error= OPEN_FRM_ERROR_ALREADY_ISSUED;
|
share->error= OPEN_FRM_ERROR_ALREADY_ISSUED;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
share->error= OPEN_FRM_OK;
|
share->error= OPEN_FRM_OK;
|
||||||
|
if (mariadb_view_version_get(share))
|
||||||
|
share->error= OPEN_FRM_ERROR_ALREADY_ISSUED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
share->error= OPEN_FRM_NOT_A_TABLE;
|
share->error= OPEN_FRM_NOT_A_TABLE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user