mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Fix for BDB and LOCK TABLES
This commit is contained in:
parent
3876d83ec1
commit
a94ba10f8d
15 changed files with 158 additions and 77 deletions
|
@ -22511,6 +22511,9 @@ locks while the thread is waiting for the @code{WRITE} lock. You should only
|
|||
use @code{LOW_PRIORITY WRITE} locks if you are sure that there will
|
||||
eventually be a time when no threads will have a @code{READ} lock.
|
||||
|
||||
@code{LOCK TABLES} and @code{UNLOCK TABLES} both commits any active
|
||||
transactions.
|
||||
|
||||
When you use @code{LOCK TABLES}, you must lock all tables that you are
|
||||
going to use and you must use the same alias that you are going to use
|
||||
in your queries! If you are using a table multiple times in a query
|
||||
|
@ -43940,6 +43943,8 @@ not yet 100% confident in this code.
|
|||
@appendixsubsec Changes in release 3.23.38
|
||||
@itemize @bullet
|
||||
@item
|
||||
Lots of portability fixes for InnoDB.
|
||||
@item
|
||||
Changed optimizer so that queries like
|
||||
@code{SELECT * FROM table_name,table_name2 ... ORDER BY key_part1 LIMIT #}
|
||||
will use index on @code{key_part1} instead of @code{filesort}.
|
||||
|
@ -43947,13 +43952,15 @@ will use index on @code{key_part1} instead of @code{filesort}.
|
|||
Fixed bug when doing
|
||||
@code{LOCK TABLE to_table WRITE,...; INSERT INTO to_table... SELECT ...}
|
||||
when to_table was empty.
|
||||
@item
|
||||
Fixed bug with @code{LOCK TABLE} and BDB tables.
|
||||
@end itemize
|
||||
|
||||
@node News-3.23.37, News-3.23.36, News-3.23.38, News-3.23.x
|
||||
@appendixsubsec Changes in release 3.23.37
|
||||
@itemize @bullet
|
||||
@item
|
||||
Fixed a bug when using MATCH in HAVING clause.
|
||||
Fixed a bug when using @code{MATCH} in @code{HAVING} clause.
|
||||
@item
|
||||
Fixed a bug when using @code{HEAP} tables with @code{LIKE}.
|
||||
@item
|
||||
|
@ -43977,7 +43984,7 @@ with @code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START} after a manual sanity
|
|||
check/correction of data integrity
|
||||
@item
|
||||
Fixed bug that erroneously logged a drop of internal temporary table
|
||||
on thread termination to the binary log - bug affected replication
|
||||
on thread termination to the binary log - bug affected replication
|
||||
@item
|
||||
Fixed a bug in @code{REGEXP()} on 64-bit machines.
|
||||
@item
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/* ib_config.h. Generated automatically by configure. */
|
||||
/* ib_config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
/* #undef inline */
|
||||
|
||||
/* Define if your processor stores words with the most significant
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* The number of bytes in a int. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* Define if you have the sched_yield function. */
|
||||
#define HAVE_SCHED_YIELD 1
|
||||
|
||||
/* Define if you have the <aio.h> header file. */
|
||||
#define HAVE_AIO_H 1
|
||||
|
||||
/* Define if you have the <sched.h> header file. */
|
||||
#define HAVE_SCHED_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "ib"
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.90"
|
||||
|
||||
/* No inlining because gcc broken on HP-UX */
|
||||
/* #undef UNIV_MUST_NOT_INLINE */
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* ib_config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
#undef inline
|
||||
|
||||
/* Define if your processor stores words with the most significant
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* The number of bytes in a int. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* Define if you have the sched_yield function. */
|
||||
#undef HAVE_SCHED_YIELD
|
||||
|
||||
/* Define if you have the <aio.h> header file. */
|
||||
#undef HAVE_AIO_H
|
||||
|
||||
/* Define if you have the <sched.h> header file. */
|
||||
#undef HAVE_SCHED_H
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* No inlining because gcc broken on HP-UX */
|
||||
#undef UNIV_MUST_NOT_INLINE
|
||||
|
|
@ -335,11 +335,10 @@ int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
|
|||
int _mi_writeinfo(register MI_INFO *info, uint operation)
|
||||
{
|
||||
int error,olderror;
|
||||
MYISAM_SHARE *share;
|
||||
MYISAM_SHARE *share=info->s;
|
||||
DBUG_ENTER("_mi_writeinfo");
|
||||
|
||||
error=0;
|
||||
share=info->s;
|
||||
if (share->r_locks == 0 && share->w_locks == 0)
|
||||
{
|
||||
olderror=my_errno; /* Remember last error */
|
||||
|
@ -368,7 +367,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
|
|||
{
|
||||
share->changed= 1; /* Mark keyfile changed */
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
DBUG_RETURN(error);
|
||||
} /* _mi_writeinfo */
|
||||
|
||||
|
||||
|
|
|
@ -492,3 +492,20 @@ a 1
|
|||
a 2
|
||||
MIN(B) MAX(b)
|
||||
1 1
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id id3
|
||||
0 0
|
||||
1 1
|
||||
2 2
|
||||
100 2
|
||||
|
|
|
@ -449,3 +449,20 @@ a
|
|||
1
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 range PRIMARY PRIMARY 4 NULL 1 where used
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id
|
||||
0
|
||||
1
|
||||
2
|
||||
id id3
|
||||
0 0
|
||||
1 1
|
||||
2 2
|
||||
100 2
|
||||
|
|
|
@ -678,3 +678,30 @@ CREATE TABLE t1 (
|
|||
INSERT INTO t1 VALUES (1, 1);
|
||||
SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test problem with BDB and lock tables with duplicate write.
|
||||
#
|
||||
|
||||
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
|
||||
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
|
||||
LOCK TABLES t1 WRITE;
|
||||
--error 690
|
||||
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
|
||||
select id from t1;
|
||||
select id from t1;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
||||
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=bdb;
|
||||
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
|
||||
LOCK TABLES t1 WRITE;
|
||||
begin;
|
||||
--error 690
|
||||
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
|
||||
select id from t1;
|
||||
insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
|
||||
commit;
|
||||
select id,id3 from t1;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -429,3 +429,30 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h
|
|||
insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
|
||||
explain select * from t1 where a > 0 and a < 50;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test lock tables
|
||||
#
|
||||
|
||||
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
|
||||
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
|
||||
LOCK TABLES t1 WRITE;
|
||||
--error 690
|
||||
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
|
||||
select id from t1;
|
||||
select id from t1;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
||||
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb;
|
||||
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
|
||||
LOCK TABLES t1 WRITE;
|
||||
begin;
|
||||
--error 690
|
||||
insert into t1 values (99,1,2,'D'),(1,1,2,'D');
|
||||
select id from t1;
|
||||
insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
|
||||
commit;
|
||||
select id,id3 from t1;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -39,11 +39,6 @@ $opt_read_key_loop_count=$opt_loop_count;
|
|||
chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
|
||||
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
|
||||
|
||||
if ($opt_loop_count < 256)
|
||||
{
|
||||
$opt_loop_count=256; # Some tests must have some data to work!
|
||||
}
|
||||
|
||||
if ($opt_small_test)
|
||||
{
|
||||
$opt_loop_count/=100;
|
||||
|
@ -62,6 +57,13 @@ elsif ($opt_small_key_tables)
|
|||
$many_keys_loop_count/=10;
|
||||
}
|
||||
|
||||
if ($opt_loop_count < 100)
|
||||
{
|
||||
$opt_loop_count=100; # Some tests must have some data to work!
|
||||
}
|
||||
$range_loop_count=min($opt_loop_count,$range_loop_count);
|
||||
|
||||
|
||||
print "Testing the speed of inserting data into 1 table and do some selects on it.\n";
|
||||
print "The tests are done with a table that has $opt_loop_count rows.\n\n";
|
||||
|
||||
|
|
|
@ -41,10 +41,9 @@
|
|||
from the updated tables.
|
||||
|
||||
Testing of:
|
||||
- LOCK TABLES
|
||||
- Mark tables that participate in a transaction so that they are not
|
||||
closed during the transaction. We need to test what happens if
|
||||
MySQL closes a table that is updated by a not commit transaction.
|
||||
MySQL closes a table that is updated by a not commited transaction.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -1701,12 +1700,35 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
|
|||
DBUG_PRINT("trans",("commiting non-updating transaction"));
|
||||
error=txn_commit((DB_TXN*) thd->transaction.stmt.bdb_tid,0);
|
||||
thd->transaction.stmt.bdb_tid=0;
|
||||
transaction=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
When using LOCK TABLE's external_lock is only called when the actual
|
||||
TABLE LOCK is done.
|
||||
Under LOCK TABLES, each used tables will force a call to start_stmt.
|
||||
*/
|
||||
|
||||
int ha_berkeley::start_stmt(THD *thd)
|
||||
{
|
||||
int error=0;
|
||||
DBUG_ENTER("ha_berkeley::start_stmt");
|
||||
if (!thd->transaction.stmt.bdb_tid)
|
||||
{
|
||||
error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid,
|
||||
(DB_TXN**) &thd->transaction.stmt.bdb_tid,
|
||||
0);
|
||||
transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The idea with handler::store_lock() is the following:
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ class ha_berkeley: public handler
|
|||
int extra(enum ha_extra_function operation);
|
||||
int reset(void);
|
||||
int external_lock(THD *thd, int lock_type);
|
||||
int start_stmt(THD *thd);
|
||||
void position(byte *record);
|
||||
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
|
||||
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
|
||||
|
|
|
@ -265,6 +265,7 @@ public:
|
|||
virtual int extra(enum ha_extra_function operation)=0;
|
||||
virtual int reset()=0;
|
||||
virtual int external_lock(THD *thd, int lock_type)=0;
|
||||
virtual int start_stmt(THD *thd) {return 0;}
|
||||
virtual int delete_all_rows();
|
||||
virtual longlong get_auto_increment();
|
||||
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
|
||||
|
@ -344,6 +345,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
|||
bool update_create_info);
|
||||
int ha_delete_table(enum db_type db_type, const char *path);
|
||||
void ha_key_cache(void);
|
||||
int ha_start_stmt(THD *thd);
|
||||
int ha_commit_trans(THD *thd, THD_TRANS *trans);
|
||||
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
|
||||
int ha_autocommit_or_rollback(THD *thd, int error);
|
||||
|
|
|
@ -1399,6 +1399,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
|
|||
&refresh)) && refresh) ;
|
||||
if (table)
|
||||
{
|
||||
int error;
|
||||
table_list->table=table;
|
||||
table->grant= table_list->grant;
|
||||
if (thd->locked_tables)
|
||||
|
@ -1410,7 +1411,12 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
|
|||
my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,
|
||||
ER(ER_TABLE_NOT_LOCKED_FOR_WRITE),
|
||||
MYF(0),table_list->name);
|
||||
DBUG_RETURN(0);
|
||||
table=0;
|
||||
}
|
||||
else if ((error=table->file->start_stmt(thd)))
|
||||
{
|
||||
table->file->print_error(error,MYF(0));
|
||||
table=0;
|
||||
}
|
||||
thd->proc_info=0;
|
||||
DBUG_RETURN(table);
|
||||
|
@ -1437,10 +1443,10 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
|
|||
|
||||
int lock_tables(THD *thd,TABLE_LIST *tables)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
if (tables && !thd->locked_tables)
|
||||
{
|
||||
uint count=0;
|
||||
TABLE_LIST *table;
|
||||
for (table = tables ; table ; table=table->next)
|
||||
count++;
|
||||
TABLE **start,**ptr;
|
||||
|
@ -1451,6 +1457,18 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
|
|||
if (!(thd->lock=mysql_lock_tables(thd,start,count)))
|
||||
return -1; /* purecov: inspected */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (table = tables ; table ; table=table->next)
|
||||
{
|
||||
int error;
|
||||
if ((error=table->table->file->start_stmt(thd)))
|
||||
{
|
||||
table->table->file->print_error(error,MYF(0));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1830,6 +1830,7 @@ mysql_execute_command(void)
|
|||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
end_active_trans(thd);
|
||||
}
|
||||
if (thd->global_read_lock)
|
||||
{
|
||||
|
|
|
@ -2525,7 +2525,6 @@ join_free(JOIN *join)
|
|||
delete tab->select;
|
||||
delete tab->quick;
|
||||
x_free(tab->cache.buff);
|
||||
end_read_record(&tab->read_record);
|
||||
if (tab->table)
|
||||
{
|
||||
if (tab->table->key_read)
|
||||
|
@ -2533,8 +2532,11 @@ join_free(JOIN *join)
|
|||
tab->table->key_read=0;
|
||||
tab->table->file->extra(HA_EXTRA_NO_KEYREAD);
|
||||
}
|
||||
tab->table->file->index_end();
|
||||
/* Don't free index if we are using read_record */
|
||||
if (!tab->read_record.table)
|
||||
tab->table->file->index_end();
|
||||
}
|
||||
end_read_record(&tab->read_record);
|
||||
}
|
||||
join->table=0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue