summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-10-18 21:19:33 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-10-18 21:19:33 +0300
commit2eb3c5e5420a724945a4cba914df25aa1e3744ce (patch)
tree52c1126949fd3fa6c79abbe064b503407c544281
parentda4503e956ee067947e504c6e73052d9d906742c (diff)
downloadmariadb-git-2eb3c5e5420a724945a4cba914df25aa1e3744ce.tar.gz
MDEV-13918 Race condition between INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS and ALTER/DROP/TRUNCATE TABLE
i_s_sys_tables_fill_table_stats(): Acquire dict_operation_lock S-latch before acquiring dict_sys->mutex, to prevent the table from being removed from the data dictionary cache and from being freed while i_s_dict_fill_sys_tablestats() is accessing the table handle.
-rw-r--r--storage/innobase/handler/i_s.cc4
-rw-r--r--storage/xtradb/handler/i_s.cc4
2 files changed, 8 insertions, 0 deletions
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 2f5fe45656e..41f4114494d 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -6403,6 +6403,7 @@ i_s_sys_tables_fill_table_stats(
}
heap = mem_heap_create(1000);
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
@@ -6429,9 +6430,11 @@ i_s_sys_tables_fill_table_stats(
err_msg);
}
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_empty(heap);
/* Get the next record */
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
@@ -6439,6 +6442,7 @@ i_s_sys_tables_fill_table_stats(
mtr_commit(&mtr);
mutex_exit(&dict_sys->mutex);
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_free(heap);
DBUG_RETURN(0);
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index aac1074e152..011bc77dc3c 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -6384,6 +6384,7 @@ i_s_sys_tables_fill_table_stats(
}
heap = mem_heap_create(1000);
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
@@ -6410,9 +6411,11 @@ i_s_sys_tables_fill_table_stats(
err_msg);
}
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_empty(heap);
/* Get the next record */
+ rw_lock_s_lock(&dict_operation_lock);
mutex_enter(&dict_sys->mutex);
mtr_start(&mtr);
rec = dict_getnext_system(&pcur, &mtr);
@@ -6420,6 +6423,7 @@ i_s_sys_tables_fill_table_stats(
mtr_commit(&mtr);
mutex_exit(&dict_sys->mutex);
+ rw_lock_s_unlock(&dict_operation_lock);
mem_heap_free(heap);
DBUG_RETURN(0);