mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Fixing bug when using alter table on locked maria table
Reset history when we reenable logging for transactional tables (safety fix) mysql-test/r/maria2.result: New results mysql-test/t/maria2.test: Added test case for alter table on locked maria table mysql-test/valgrind.supp: Added suppression rules for warnings in libc / libld storage/maria/ma_extra.c: Remove table from trnman list if we are going to drop or rename it; We don't want not existing shares in the list when we do commit! storage/maria/ma_recovery.c: Ensure that info->state don't point to history event when we disable logging for a table; This is needed as alter table will first do commit and then unlock, which would cause us to access a non existing object when we reenable logging. Reset history when we reenable logging (safety fix) storage/maria/ma_state.c: Do less work when share->now_transactional is not set. (Safety fix) Added function to remove shares to be deleted from trnman->used_tables Added function to reset history to current context storage/maria/ma_state.h: Prototypes for new function
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
drop table if exists t1,t2;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
line BLOB,
|
line BLOB,
|
||||||
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
|
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
|
||||||
@@ -16,3 +17,16 @@ check table t1 extended;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (i int) engine=maria;
|
||||||
|
create table t2 (j int) engine=maria;
|
||||||
|
lock table t1 write, t2 read;
|
||||||
|
alter table t1 modify i int default 1;
|
||||||
|
insert into t1 values (2);
|
||||||
|
alter table t1 modify i bigint default 1;
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
1
|
||||||
|
select * from t1;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
drop table t1,t2;
|
||||||
|
@@ -1,5 +1,10 @@
|
|||||||
--source include/have_maria.inc
|
--source include/have_maria.inc
|
||||||
|
|
||||||
|
# Initialise
|
||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
# Test for BUG#36319
|
# Test for BUG#36319
|
||||||
# "Maria: table is not empty but DELETE and SELECT find no rows"
|
# "Maria: table is not empty but DELETE and SELECT find no rows"
|
||||||
|
|
||||||
@@ -64,3 +69,19 @@ select count(*) from t1;
|
|||||||
select name from t1;
|
select name from t1;
|
||||||
check table t1 extended;
|
check table t1 extended;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing of ALTER TABLE under lock tables
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (i int) engine=maria;
|
||||||
|
create table t2 (j int) engine=maria;
|
||||||
|
lock table t1 write, t2 read;
|
||||||
|
alter table t1 modify i int default 1;
|
||||||
|
insert into t1 values (2);
|
||||||
|
# This caused a core dump
|
||||||
|
alter table t1 modify i bigint default 1;
|
||||||
|
select count(*) from t1;
|
||||||
|
select * from t1;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
pthread allocate_tls memory loss
|
pthread allocate_tls memory loss
|
||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
fun:calloc
|
fun:calloc
|
||||||
obj:/lib64/ld*.so
|
obj:/lib*/ld*.so
|
||||||
fun:_dl_allocate_tls
|
fun:_dl_allocate_tls
|
||||||
fun:pthread_create*
|
fun:pthread_create*
|
||||||
}
|
}
|
||||||
@@ -388,40 +388,58 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
|
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit
|
||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
fun:*alloc
|
fun:*alloc
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/libc-*.so
|
obj:/lib*/libc-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/libc-*.so
|
obj:/lib*/libc-*.so
|
||||||
fun:__libc_dlopen_mode
|
fun:__libc_dlopen_mode
|
||||||
fun:pthread_cancel_init
|
fun:pthread_cancel_init
|
||||||
fun:_Unwind_ForcedUnwind
|
fun:_Unwind_ForcedUnwind
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
|
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit
|
||||||
Memcheck:Leak
|
Memcheck:Leak
|
||||||
fun:*alloc
|
fun:*alloc
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/libc-*.so
|
obj:/lib*/libc-*.so
|
||||||
obj:/lib64/ld-*.so
|
obj:/lib*/ld-*.so
|
||||||
obj:/lib64/libc-*.so
|
obj:/lib*/libc-*.so
|
||||||
fun:__libc_dlopen_mode
|
fun:__libc_dlopen_mode
|
||||||
fun:pthread_cancel_init
|
fun:pthread_cancel_init
|
||||||
fun:_Unwind_ForcedUnwind
|
fun:_Unwind_ForcedUnwind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reading wrong addresses on SuSe Linux 10.3 32 bit
|
||||||
|
#
|
||||||
|
|
||||||
|
{
|
||||||
|
Reading wrong data in libc_dlopen
|
||||||
|
Memcheck:Addr4
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/libc-*.so
|
||||||
|
obj:/lib*/ld-*.so
|
||||||
|
obj:/lib*/libc-*.so
|
||||||
|
fun:__libc_dlopen_mode
|
||||||
|
fun:pthread_cancel_init
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# These seem to be libc threading stuff, not related to MySQL code (allocations
|
# These seem to be libc threading stuff, not related to MySQL code (allocations
|
||||||
|
@@ -322,6 +322,13 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
|||||||
if (share->kfile.file >= 0)
|
if (share->kfile.file >= 0)
|
||||||
_ma_decrement_open_count(info);
|
_ma_decrement_open_count(info);
|
||||||
pthread_mutex_lock(&share->intern_lock);
|
pthread_mutex_lock(&share->intern_lock);
|
||||||
|
if (info->trn)
|
||||||
|
{
|
||||||
|
_ma_remove_table_from_trnman(share, info->trn);
|
||||||
|
/* Ensure we don't point to the deleted data in trn */
|
||||||
|
info->state= &share->state.state;
|
||||||
|
}
|
||||||
|
|
||||||
type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
|
type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
|
||||||
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
|
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
|
||||||
type, type))
|
type, type))
|
||||||
|
@@ -3214,6 +3214,16 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
|
|||||||
|
|
||||||
/* if we disabled before writing the record, record wouldn't reach log */
|
/* if we disabled before writing the record, record wouldn't reach log */
|
||||||
share->now_transactional= FALSE;
|
share->now_transactional= FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reset state pointers. This is needed as in ALTER table we may do
|
||||||
|
commit fllowed by _ma_renable_logging_for_table and then
|
||||||
|
info->state may point to a state that was deleted by
|
||||||
|
_ma_trnman_end_trans_hook()
|
||||||
|
*/
|
||||||
|
share->state.common= *info->state;
|
||||||
|
info->state= &share->state.common;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some code in ma_blockrec.c assumes a trn even if !now_transactional but in
|
Some code in ma_blockrec.c assumes a trn even if !now_transactional but in
|
||||||
this case it only reads trn->rec_lsn, which has to be LSN_IMPOSSIBLE and
|
this case it only reads trn->rec_lsn, which has to be LSN_IMPOSSIBLE and
|
||||||
@@ -3255,6 +3265,7 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
|
|||||||
in not transactional mode
|
in not transactional mode
|
||||||
*/
|
*/
|
||||||
_ma_copy_nontrans_state_information(info);
|
_ma_copy_nontrans_state_information(info);
|
||||||
|
_ma_reset_history(info->s);
|
||||||
|
|
||||||
if (flush_pages)
|
if (flush_pages)
|
||||||
{
|
{
|
||||||
|
@@ -371,7 +371,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
|||||||
MARIA_STATE_HISTORY *history;
|
MARIA_STATE_HISTORY *history;
|
||||||
|
|
||||||
pthread_mutex_lock(&share->intern_lock);
|
pthread_mutex_lock(&share->intern_lock);
|
||||||
if (active_transactions &&
|
if (active_transactions && share->now_transactional &&
|
||||||
trnman_exists_active_transactions(share->state_history->trid,
|
trnman_exists_active_transactions(share->state_history->trid,
|
||||||
trn->commit_trid, 1))
|
trn->commit_trid, 1))
|
||||||
{
|
{
|
||||||
@@ -415,6 +415,35 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove table from trnman_list
|
||||||
|
|
||||||
|
@notes
|
||||||
|
This is used when we unlock a table from a group of locked tables
|
||||||
|
just before doing a rename or drop table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
|
||||||
|
{
|
||||||
|
MARIA_USED_TABLES *tables, **prev;
|
||||||
|
|
||||||
|
for (prev= (MARIA_USED_TABLES**) &trn->used_tables, tables= *prev;
|
||||||
|
tables;
|
||||||
|
tables= *prev)
|
||||||
|
{
|
||||||
|
if (tables->share == share)
|
||||||
|
{
|
||||||
|
*prev= tables->next;
|
||||||
|
my_free(tables, MYF(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prev= &tables->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
The following functions are called by thr_lock() in threaded applications
|
The following functions are called by thr_lock() in threaded applications
|
||||||
for transactional tables.
|
for transactional tables.
|
||||||
@@ -509,6 +538,23 @@ void _ma_copy_nontrans_state_information(MARIA_HA *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _ma_reset_history(MARIA_SHARE *share)
|
||||||
|
{
|
||||||
|
MARIA_STATE_HISTORY *history, *next;
|
||||||
|
|
||||||
|
share->state_history->trid= 0; /* Visibly by all */
|
||||||
|
share->state_history->state= share->state.state;
|
||||||
|
history= share->state_history->next;
|
||||||
|
share->state_history->next= 0;
|
||||||
|
|
||||||
|
for (; history; history= next)
|
||||||
|
{
|
||||||
|
next= history->next;
|
||||||
|
my_free(history, MYF(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Virtual functions to check if row is visible
|
Virtual functions to check if row is visible
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@@ -77,3 +77,5 @@ my_bool _ma_row_visible_always(MARIA_HA *info);
|
|||||||
my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
|
my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
|
||||||
my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
|
my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
|
||||||
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share);
|
void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share);
|
||||||
|
void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn);
|
||||||
|
void _ma_reset_history(struct st_maria_share *share);
|
||||||
|
Reference in New Issue
Block a user