Commit 123e31ce authored by unknown's avatar unknown

Fix for BDB and LOCK TABLES


BitKeeper/deleted/.del-ib_config.h.in~9e57db8504e55b7:
  Delete: innobase/ib_config.h.in
BitKeeper/deleted/.del-ib_config.h~7539e26ffc614439:
  Delete: innobase/ib_config.h
Docs/manual.texi:
  Changelog
myisam/mi_locking.c:
  Cleanup
mysql-test/r/bdb.result:
  Test for LOCK TABLES
mysql-test/r/innodb.result:
  Test for LOCK TABLES
mysql-test/t/bdb.test:
  Test for LOCK TABLES
mysql-test/t/innodb.test:
  Test for LOCK TABLES
sql-bench/test-insert.sh:
  Allow loop to be small
sql/ha_berkeley.cc:
  Fixed bug when using LOCK TABLES with BDB
sql/ha_berkeley.h:
  Fixed bug when using LOCK TABLES with BDB
sql/handler.h:
  Fixed bug when using LOCK TABLES with BDB
sql/sql_base.cc:
  Fixed bug when using LOCK TABLES with BDB
sql/sql_parse.cc:
  UNLOCK TABLES ends transaction
sql/sql_select.cc:
  Fix to not call index_end() twice
parent aabac446
......@@ -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
/* 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 */
/* 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 @@ class handler :public Sql_alloc
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment