summaryrefslogtreecommitdiff
path: root/storage/myisammrg/ha_myisammrg.h
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-12-08 16:57:25 +0300
committerKonstantin Osipov <kostja@sun.com>2009-12-08 16:57:25 +0300
commit463dcbb51ccea25b07e7b6d0d3787120c4fa895d (patch)
tree793d0dad1581ef83133f9fc62cb89d7823dea4a3 /storage/myisammrg/ha_myisammrg.h
parentce5c87a3d359d528111d84b5c75bdb8acfe3fb9c (diff)
downloadmariadb-git-463dcbb51ccea25b07e7b6d0d3787120c4fa895d.tar.gz
Backport of revid 2617.69.21, 2617.69.22, 2617.29.23:
---------------------------------------------------------- revno: 2617.69.21 committer: Konstantin Osipov <kostja@sun.com> branch nick: 5.4-4284-1-assert timestamp: Thu 2009-08-13 20:13:55 +0400 message: A fix and a test case for Bug#46610 "MySQL 5.4.4: MyISAM MRG engine crash on auto-repair of child". Also fixes Bug#42862 "Crash on failed attempt to open a children of a merge table". MERGE engine needs to extend the global table list with TABLE_LIST elements for child tables, so that they are opened and locked. Previously these table list elements were allocated in memory of ha_myisammrg object (MERGE engine handler). That would lead to access to freed memory in recover_from_failed_open_table_attempt(), which would try to recover a MERGE table child (MyISAM table) and use for that TABLE_LIST of that child. But by the time recover_from_failed_open_table_attempt() is invoked, ha_myisammrg object that owns this TABLE_LIST may be destroyed, and thus TABLE_LIST memory freed. The fix is to ensure that TABLE_LIST elements that are added to the global table list (lex->query_tables) are always allocated in thd->mem_root, which is not destroyed until end of execution. If previously TABLE_LIST elements were allocated at ha_myisammrg::open() (i.e. when the TABLE object was created and added to the table cache), now they are allocated in ha_myisammrg::add_chidlren_list() (i.e. right after "open" of the merge parent in open_tables()). We still create a list of children names at ha_myisammrg::open() to use as a basis for creation of TABLE_LISTs, that allows to avoid reading the merge handler data file on every execution. mysql-test/r/merge_recover.result: Test results for Bug#46610. mysql-test/t/merge_recover-master.opt: Option file for Bug#46610 test (need a new test because of that option, which is not tested anywhere else). mysql-test/t/merge_recover.test: Add a test case for Bug#46610. sql/table.h: MERGE child child_def_version is now moved from TABLE_LIST to MERGE engine specific data structure. storage/myisammrg/ha_myisammrg.cc: Introduce an auxiliary structure to keep MERGE child name and definition version. A list of Mrg_child_def is created in ha_myisammrg::open() and reused in ha_myisammrg::add_children_list().
Diffstat (limited to 'storage/myisammrg/ha_myisammrg.h')
-rw-r--r--storage/myisammrg/ha_myisammrg.h50
1 files changed, 47 insertions, 3 deletions
diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h
index c3803eb584b..4ff24c69071 100644
--- a/storage/myisammrg/ha_myisammrg.h
+++ b/storage/myisammrg/ha_myisammrg.h
@@ -22,18 +22,62 @@
#include <myisammrg.h>
+/**
+ Represents one name of a MERGE child.
+
+ @todo: Add MYRG_SHARE and store chlidren names in the
+ share.
+*/
+
+class Mrg_child_def: public Sql_alloc
+{
+ /* Remembered MERGE child def version. See top comment in ha_myisammrg.cc */
+ enum_table_ref_type m_child_table_ref_type;
+ ulong m_child_def_version;
+public:
+ LEX_STRING db;
+ LEX_STRING name;
+
+ /* Access MERGE child def version. See top comment in ha_myisammrg.cc */
+ inline enum_table_ref_type get_child_table_ref_type()
+ {
+ return m_child_table_ref_type;
+ }
+ inline ulong get_child_def_version()
+ {
+ return m_child_def_version;
+ }
+ inline void set_child_def_version(enum_table_ref_type child_table_ref_type,
+ ulong version)
+ {
+ m_child_table_ref_type= child_table_ref_type;
+ m_child_def_version= version;
+ }
+
+ Mrg_child_def(char *db_arg, size_t db_len_arg,
+ char *table_name_arg, size_t table_name_len_arg)
+ {
+ db.str= db_arg;
+ db.length= db_len_arg;
+ name.str= table_name_arg;
+ name.length= table_name_len_arg;
+ m_child_def_version= ~0UL;
+ m_child_table_ref_type= TABLE_REF_NULL;
+ }
+};
+
+
class ha_myisammrg: public handler
{
MYRG_INFO *file;
my_bool is_cloned; /* This instance has been cloned */
- public:
+public:
MEM_ROOT children_mem_root; /* mem root for children list */
+ List<Mrg_child_def> child_def_list;
TABLE_LIST *children_l; /* children list */
TABLE_LIST **children_last_l; /* children list end */
- TABLE_LIST *next_child_attach; /* next child to attach */
uint test_if_locked; /* flags from ::open() */
- bool need_compat_check; /* if need compatibility check */
ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg);
~ha_myisammrg();