diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2017-12-21 18:24:58 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2017-12-21 18:24:58 +0300 |
commit | e6c5eb5c583b2789861b9042fe584608d6450837 (patch) | |
tree | db98ce224464fd44c031ccb444a3e78999cefaa3 /sql/partition_info.cc | |
parent | 7e39f7004415517cbbd51c3cd53049d5e5cd5c52 (diff) | |
download | mariadb-git-e6c5eb5c583b2789861b9042fe584608d6450837.tar.gz |
MDEV-14730 Assertion `m_lock_type == 2' failed in handler::ha_close
SQL: class Table_locker
Diffstat (limited to 'sql/partition_info.cc')
-rw-r--r-- | sql/partition_info.cc | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/sql/partition_info.cc b/sql/partition_info.cc index a25ee53cbab..ec6cebcafb8 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -34,6 +34,7 @@ #include "sql_base.h" // fill_record #include "sql_statistics.h" // vers_stat_end #include "vers_utils.h" +#include "lock.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" @@ -1030,6 +1031,49 @@ bool partition_info::vers_setup_expression(THD * thd, uint32 alter_add) } +class Table_locker +{ + THD *thd; + TABLE &table; + thr_lock_type saved_mode; + TABLE_LIST table_list; + MYSQL_LOCK *saved_lock; + bool locked; + +public: + Table_locker(THD *_thd, TABLE &_table, thr_lock_type lock_type) : + thd(_thd), + table(_table), + saved_mode(table.reginfo.lock_type), + table_list(_table, lock_type), + saved_lock(_thd->lock), + locked(false) + { + table.reginfo.lock_type= lock_type; + } + bool lock() + { + DBUG_ASSERT(table.file); + // FIXME: check consistency with table.reginfo.lock_type + if (table.file->get_lock_type() != F_UNLCK) + return false; + thd->lock= NULL; + bool res= lock_tables(thd, &table_list, 1, 0); + locked= !res; + return res; + } + ~Table_locker() + { + if (locked) + mysql_unlock_tables(thd, thd->lock); + table.reginfo.lock_type= saved_mode; + thd->lock= saved_lock; + if (locked && !thd->in_sub_stmt) + ha_commit_trans(thd, false); + } +}; + + // scan table for min/max sys_trx_end inline bool partition_info::vers_scan_min_max(THD *thd, partition_element *part) @@ -1040,22 +1084,24 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part) DBUG_ASSERT(part->empty); DBUG_ASSERT(part->type() == partition_element::HISTORY); DBUG_ASSERT(table->s->stat_trx); + + Table_locker l(thd, *table, TL_READ); + if (l.lock()) + { + my_error(ER_INTERNAL_ERROR, MYF(0), "min/max scan failed on lock_tables()"); + return true; + } + for (; part_id < part_id_end; ++part_id) { handler *file= table->file->part_handler(part_id); // requires update_partition() for ha_innopart DBUG_ASSERT(file); - int rc= file->ha_external_lock(thd, F_RDLCK); // requires ha_commit_trans() for ha_innobase - if (rc) - { - file->update_partition(part_id); - goto lock_fail; - } table->default_column_bitmaps(); bitmap_set_bit(table->read_set, table->vers_end_field()->field_index); file->column_bitmaps_signal(); - rc= file->ha_rnd_init(true); + int rc= file->ha_rnd_init(true); if (!rc) { while ((rc= file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE) @@ -1101,20 +1147,14 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part) } file->ha_rnd_end(); } - file->ha_external_lock(thd, F_UNLCK); file->update_partition(part_id); if (rc != HA_ERR_END_OF_FILE) { - if (!thd->in_sub_stmt) - ha_commit_trans(thd, false); - lock_fail: // TODO: print rc code my_error(ER_INTERNAL_ERROR, MYF(0), "min/max scan failed in versioned partitions setup (see warnings)"); return true; } } - if (!thd->in_sub_stmt) - ha_commit_trans(thd, false); return false; } @@ -1171,13 +1211,7 @@ bool partition_info::vers_setup_stats(THD * thd, bool is_create_table_ind) bool error= false; - TABLE_LIST tl; - tl.init_one_table( - LEX_STRING_WITH_LEN(table->s->db), - LEX_STRING_WITH_LEN(table->s->table_name), - table->s->table_name.str, - TL_WRITE); - + TABLE_LIST tl(*table, TL_READ); MDL_auto_lock mdl_lock(thd, tl); if (mdl_lock.acquire_error()) return true; |