Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
710b75f5
Commit
710b75f5
authored
Aug 29, 2000
by
monty@donna.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
438e8c7c
066d55c0
Changes
33
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
909 additions
and
211 deletions
+909
-211
Docs/internals.texi
Docs/internals.texi
+59
-0
Docs/manual.texi
Docs/manual.texi
+275
-147
client/mysql.cc
client/mysql.cc
+18
-8
client/mysqlimport.c
client/mysqlimport.c
+1
-2
include/config-win.h
include/config-win.h
+2
-0
include/global.h
include/global.h
+1
-1
libmysql/libmysql.c
libmysql/libmysql.c
+4
-3
myisam/ChangeLog
myisam/ChangeLog
+4
-0
myisam/Makefile.am
myisam/Makefile.am
+1
-1
myisam/ft_stopwords.c
myisam/ft_stopwords.c
+1
-1
myisam/mi_delete_table.c
myisam/mi_delete_table.c
+7
-0
myisam/mi_rename.c
myisam/mi_rename.c
+8
-0
myisam/mi_rnext.c
myisam/mi_rnext.c
+1
-1
myisam/mi_rprev.c
myisam/mi_rprev.c
+1
-1
myisam/mi_search.c
myisam/mi_search.c
+1
-0
myisam/myisamdef.h
myisam/myisamdef.h
+2
-0
scripts/make_binary_distribution.sh
scripts/make_binary_distribution.sh
+1
-1
sql/ha_heap.cc
sql/ha_heap.cc
+15
-0
sql/ha_heap.h
sql/ha_heap.h
+4
-1
sql/handler.cc
sql/handler.cc
+2
-2
sql/handler.h
sql/handler.h
+1
-1
sql/lock.cc
sql/lock.cc
+13
-9
sql/mini_client.cc
sql/mini_client.cc
+3
-2
sql/mysql_priv.h
sql/mysql_priv.h
+3
-2
sql/mysqld.cc
sql/mysqld.cc
+11
-4
sql/opt_range.cc
sql/opt_range.cc
+11
-1
sql/sql_base.cc
sql/sql_base.cc
+17
-18
sql/sql_parse.cc
sql/sql_parse.cc
+8
-4
sql/sql_select.cc
sql/sql_select.cc
+8
-0
sql/table.h
sql/table.h
+1
-0
tests/drop_test.pl
tests/drop_test.pl
+220
-0
tests/fork_test.pl
tests/fork_test.pl
+1
-1
tests/rename_test.pl
tests/rename_test.pl
+204
-0
No files found.
Docs/internals.texi
View file @
710b75f5
...
...
@@ -143,6 +143,65 @@ same tables.
and then we read the rows in the sorted order into a row buffer
(record
_
buffer) .
@node Coding guidelines
@chapter Coding guidelines
- We are using bitkeeper (www.bitkeeper.com) for source management.
- You should use the MySQL 3.23 or MySQL 4.0 source for all developments.
- If you have any questions about the MySQL source, you can post these
to developers@mysql.com and we will answer them.
Note that we will shortly change the name of this list to
internals@mysql.com, to more accurately reflect what should be
posted to this list.
- Try to write code in a lot of black boxes that can be reused or at
least have a clean interface
- Reuse code; There is already in MySQL a lot of algorithms for list handling,
queues, dynamic and hashed arrays, sorting...) that can be reused.
- Try to always write optimized code, so that you don't have to
go back and rewrite it a couple of months later. It's better to
spend 3 times as much time designing and writing and optimal function than
having to do it all over again later on.
- Avoid CPU wasteful code, even where it does not matter, so that
you will not develop sloppy coding habits.
- If you can write it in fewer lines, do it (as long as the code will not
be slower or much harder to read)
- do not check the same pointer for NULL more than once.
- Use long function and variable names in English; This makes your
code easier to read.
- Think assembly - make it easier for the compiler to optimize your code.
- Comment your code when you do something that someone else may think
is 'not trivial'.
- Use the my
_
functions like my
_
read/my
_
write/my
_
malloc() that you can
find in the mysys library instead of the direct system calls; This
will make your code easier to debug and more portable.
- use libstring functions instead of standard libc string functions
whenever possible
- Avoid using alloc (its REAL slow); For memory allocations that only
needs to live for the lifetime of one thread, on should use
sql
_
alloc() instead.
- Before doing big design decision, please first post a summary of
what you want to do, why you want to do it and how you plan to do
it. This way we can easily provide you with feedback and also
easily discuss is throughly if some other developer thinks there is better
way to do the same thing!
- Use my
_
var as opposed to myVar or MyVar (
_
rather than dancing SHIFT
to spearate words in identifiers)
- class names start with a capital
- structure types are typedefed to all caps identifier
- #defines are capitalized
- matching
{
are in the same column
- functions return 0 on success , non-zero on error, so you can do
if(a() || b() || c())
{
error("something went wrong");
}
- goto is ok if not abused
- avoid default variable initalizations, use LINT
_
INIT() if the
compiler complains after making sure that there is really no way
the variable can be used uninitialized
- Do not instantiate a class if you do not have to
- Use pointers rather than array indexing when operating on strings
@node Index
@unnumbered Index
...
...
Docs/manual.texi
View file @
710b75f5
This diff is collapsed.
Click to expand it.
client/mysql.cc
View file @
710b75f5
...
...
@@ -114,7 +114,7 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
no_rehash
=
0
,
skip_updates
=
0
,
safe_updates
=
0
,
one_database
=
0
,
opt_compress
=
0
,
vertical
=
0
,
skip_line_numbers
=
0
,
skip_column_names
=
0
,
opt_html
=
0
,
no_named_cmds
=
0
;
no_named_cmds
=
1
;
// we want this to be the default
static
uint
verbose
=
0
,
opt_silent
=
0
,
opt_mysql_port
=
0
;
static
my_string
opt_mysql_unix_port
=
0
;
static
int
connect_flag
=
CLIENT_INTERACTIVE
;
...
...
@@ -160,7 +160,7 @@ typedef struct {
static
COMMANDS
commands
[]
=
{
{
"help"
,
'h'
,
com_help
,
0
,
"Display this text"
},
{
"?"
,
'
h
'
,
com_help
,
0
,
"Synonym for `help'"
},
{
"?"
,
'
?
'
,
com_help
,
0
,
"Synonym for `help'"
},
{
"clear"
,
'c'
,
com_clear
,
0
,
"Clear command"
},
{
"connect"
,
'r'
,
com_connect
,
1
,
"Reconnect to the server. Optional arguments are db and host"
},
...
...
@@ -300,7 +300,7 @@ int main(int argc,char *argv[])
}
}
#endif
sprintf
(
buff
,
"Type '
%s' for help.
\n
"
,
no_named_cmds
?
"
\\
h"
:
"help
"
);
sprintf
(
buff
,
"Type '
help;' or '
\\
h' for help.
\n
"
);
put_info
(
buff
,
INFO_INFO
);
status
.
exit_status
=
read_lines
(
1
);
// read lines and execute them
mysql_end
(
0
);
...
...
@@ -352,6 +352,7 @@ static struct option long_options[] =
{
"database"
,
required_argument
,
0
,
'D'
},
{
"debug-info"
,
no_argument
,
0
,
'T'
},
{
"default-character-set"
,
required_argument
,
0
,
OPT_DEFAULT_CHARSET
},
{
"enable-named-commands"
,
no_argument
,
0
,
'G'
},
{
"execute"
,
required_argument
,
0
,
'e'
},
{
"force"
,
no_argument
,
0
,
'f'
},
{
"help"
,
no_argument
,
0
,
'?'
},
...
...
@@ -401,7 +402,7 @@ CHANGEABLE_VAR changeable_vars[] = {
static
void
usage
(
int
version
)
{
printf
(
"%s Ver 10.
8
Distrib %s, for %s (%s)
\n
"
,
printf
(
"%s Ver 10.
10
Distrib %s, for %s (%s)
\n
"
,
my_progname
,
MYSQL_SERVER_VERSION
,
SYSTEM_TYPE
,
MACHINE_TYPE
);
if
(
version
)
return
;
...
...
@@ -426,11 +427,17 @@ static void usage(int version)
-D, --database=.. Database to use.
\n
\
--default-character-set=...
\n
\
Set the default character set.
\n
\
-G, --enable-named-commands
\n
\
Named commands are enabled. Opposite to -g.
\n
\
-e, --execute=... Execute command and quit. (Output like with --batch)
\n
\
-E, --vertical Print the output of a query (rows) vertically.
\n
\
-f, --force Continue even if we get an sql error.
\n
\
-g, --no-named-commands
\n
\
Named commands are disabled. Use
\\
* form only.
\n
\
Named commands are disabled. Use
\\
* form only, or
\n
\
use named commands only in the beginning of a line
\n
\
ending with a semicolon (;)
\n
\
Since version 10.9 the client now starts with this
\n
\
option ENABLED by default! Disable with '-G'
\n
\
-i, --ignore-space Ignore space after function names.
\n
\
-h, --host=... Connect to host.
\n
\
-H, --html Produce HTML output.
\n
\
...
...
@@ -486,7 +493,7 @@ static int get_options(int argc, char **argv)
bool
tty_password
=
0
;
set_all_changeable_vars
(
changeable_vars
);
while
((
c
=
getopt_long
(
argc
,
argv
,
"?ABCD:LfgHinNoqrstTUvVwWEe:h:O:P:S:u:#::p::"
,
while
((
c
=
getopt_long
(
argc
,
argv
,
"?ABCD:Lfg
G
HinNoqrstTUvVwWEe:h:O:P:S:u:#::p::"
,
long_options
,
&
option_index
))
!=
EOF
)
{
switch
(
c
)
{
...
...
@@ -565,6 +572,7 @@ static int get_options(int argc, char **argv)
case
'E'
:
vertical
=
1
;
break
;
case
'w'
:
wait_flag
=
1
;
break
;
case
'A'
:
no_rehash
=
1
;
break
;
case
'G'
:
no_named_cmds
=
0
;
break
;
case
'g'
:
no_named_cmds
=
1
;
break
;
case
'H'
:
opt_html
=
1
;
break
;
case
'i'
:
connect_flag
|=
CLIENT_IGNORE_SPACE
;
break
;
...
...
@@ -1171,11 +1179,13 @@ com_help (String *buffer __attribute__((unused)),
reg1
int
i
;
put_info
(
"
\n
MySQL commands:"
,
INFO_INFO
);
if
(
no_named_cmds
)
put_info
(
"Note that all text commands must be first on line and end with ';'"
,
INFO_INFO
);
for
(
i
=
0
;
commands
[
i
].
name
;
i
++
)
{
if
(
commands
[
i
].
func
)
printf
(
"%s
\t
(
\\
%c)
\t
%s
\n
"
,
commands
[
i
].
name
,
commands
[
i
].
cmd_char
,
commands
[
i
].
doc
);
printf
(
"%s
\t
(
\\
%c)
\t
%s
\n
"
,
commands
[
i
].
name
,
commands
[
i
].
cmd_char
,
commands
[
i
].
doc
);
}
if
(
connected
)
printf
(
"
\n
Connection id: %ld (Can be used with mysqladmin kill)
\n\n
"
,
...
...
client/mysqlimport.c
View file @
710b75f5
...
...
@@ -25,7 +25,7 @@
** * *
** *************************
*/
#define IMPORT_VERSION "2.
3
"
#define IMPORT_VERSION "2.
4
"
#include <global.h>
#include <my_sys.h>
...
...
@@ -514,7 +514,6 @@ int main(int argc, char **argv)
exitcode
=
error
;
db_disconnect
(
current_host
,
sock
);
my_free
(
password
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
current_user
,
MYF
(
MY_ALLOW_ZERO_PTR
));
free_defaults
(
argv_to_free
);
my_end
(
0
);
return
(
exitcode
);
...
...
include/config-win.h
View file @
710b75f5
...
...
@@ -250,6 +250,8 @@ inline double ulonglong2double(ulonglong value)
#define HAVE_RINT
/* defined in this file */
#define NO_FCNTL_NONBLOCK
/* No FCNTL */
#define HAVE_ALLOCA
#define HAVE_STRPBRK
#define HAVE_STRSTR
#define HAVE_COMPRESS
#ifdef NOT_USED
...
...
include/global.h
View file @
710b75f5
...
...
@@ -110,7 +110,7 @@
#endif
/* In Linux-alpha we have atomic.h if we are using gcc */
#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95))
#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95))
&& !defined(HAVE_ATOMIC_ADD)
#define HAVE_ATOMIC_ADD
#define HAVE_ATOMIC_SUB
#endif
...
...
libmysql/libmysql.c
View file @
710b75f5
...
...
@@ -112,7 +112,8 @@ static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
static
int
connect2
(
File
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
)
static
int
connect2
(
my_socket
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
)
{
#if defined(__WIN__)
return
connect
(
s
,
(
struct
sockaddr
*
)
name
,
namelen
);
...
...
@@ -1138,7 +1139,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
uint
port
,
const
char
*
unix_socket
,
uint
client_flag
)
{
char
buff
[
100
],
charset_name_buff
[
16
],
*
end
,
*
host_info
,
*
charset_name
;
int
sock
;
my_socket
sock
;
uint32
ip_addr
;
struct
sockaddr_in
sock_addr
;
uint
pkt_length
;
...
...
@@ -1270,7 +1271,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
sprintf
(
host_info
=
buff
,
ER
(
CR_TCP_CONNECTION
),
host
);
DBUG_PRINT
(
"info"
,(
"Server name: '%s'. TCP sock: %d"
,
host
,
port
));
/* _WIN64 ; Assume that the (int) range is enough for socket() */
if
((
sock
=
(
in
t
)
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
==
SOCKET_ERROR
)
if
((
sock
=
(
my_socke
t
)
socket
(
AF_INET
,
SOCK_STREAM
,
0
))
==
SOCKET_ERROR
)
{
net
->
last_errno
=
CR_IPSOCK_ERROR
;
sprintf
(
net
->
last_error
,
ER
(
net
->
last_errno
),
ERRNO
);
...
...
myisam/ChangeLog
View file @
710b75f5
2000-08-23 Michael Widenius <monty@mysql.com>
* Fixed bug when comparing DECIMAL/NUMERIC key parts.
2000-08-17 Michael Widenius <monty@mysql.com>
* Add a new flag in share.staus so that we can quickly check if a table
...
...
myisam/Makefile.am
View file @
710b75f5
...
...
@@ -43,7 +43,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_rsamepos.c mi_panic.c mi_close.c mi_create.c
\
mi_range.c mi_dbug.c mi_checksum.c mi_log.c
\
mi_changed.c mi_static.c mi_delete_all.c
\
mi_delete_table.c mi_rename.c mi_check.c
\
mi_delete_table.c mi_rename.c mi_check.c
mi_debug.c
\
ft_parser.c ft_search.c ft_stopwords.c ft_static.c
\
ft_update.c sort.c
CLEANFILES
=
test
?.IS? isam.log mi_test_all
...
...
myisam/ft_stopwords.c
View file @
710b75f5
...
...
@@ -48,7 +48,7 @@ int ft_init_stopwords(const char **sws)
for
(;
*
sws
;
sws
++
)
{
if
(
(
sw
.
len
=
strlen
(
sw
.
pos
=*
sws
))
<
MIN_WORD_LEN
)
continue
;
if
(
(
sw
.
len
=
(
uint
)
strlen
(
sw
.
pos
=*
sws
))
<
MIN_WORD_LEN
)
continue
;
if
(
!
tree_insert
(
stopwords3
,
&
sw
,
0
))
{
delete_tree
(
stopwords3
);
...
...
myisam/mi_delete_table.c
View file @
710b75f5
...
...
@@ -30,6 +30,10 @@ int mi_delete_table(const char *name)
uint
raid_type
=
0
,
raid_chunks
=
0
;
#endif
DBUG_ENTER
(
"mi_delete_table"
);
#ifdef EXTRA_DEBUG
check_table_is_closed
(
name
,
"delete"
);
#endif
#ifdef USE_RAID
{
MI_INFO
*
info
;
...
...
@@ -39,7 +43,10 @@ int mi_delete_table(const char *name)
raid_chunks
=
info
->
s
->
base
.
raid_chunks
;
mi_close
(
info
);
}
#ifdef EXTRA_DEBUG
check_table_is_closed
(
name
,
"delete"
);
#endif
#endif
/* USE_RAID */
fn_format
(
from
,
name
,
""
,
MI_NAME_IEXT
,
4
);
if
(
my_delete
(
from
,
MYF
(
MY_WME
)))
...
...
myisam/mi_rename.c
View file @
710b75f5
...
...
@@ -30,6 +30,11 @@ int mi_rename(const char *old_name, const char *new_name)
uint
raid_type
=
0
,
raid_chunks
=
0
;
#endif
DBUG_ENTER
(
"mi_rename"
);
#ifdef EXTRA_DEBUG
check_table_is_closed
(
old_name
,
"rename old_table"
);
check_table_is_closed
(
new_name
,
"rename new table2"
);
#endif
#ifdef USE_RAID
{
MI_INFO
*
info
;
...
...
@@ -39,7 +44,10 @@ int mi_rename(const char *old_name, const char *new_name)
raid_chunks
=
info
->
s
->
base
.
raid_chunks
;
mi_close
(
info
);
}
#ifdef EXTRA_DEBUG
check_table_is_closed
(
old_name
,
"rename raidcheck"
);
#endif
#endif
/* USE_RAID */
fn_format
(
from
,
old_name
,
""
,
MI_NAME_IEXT
,
4
);
fn_format
(
to
,
new_name
,
""
,
MI_NAME_IEXT
,
4
);
...
...
myisam/mi_rnext.c
View file @
710b75f5
...
...
@@ -57,7 +57,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
/* Skip rows that are inserted by other threads since we got a lock */
if
((
error
=
_mi_search_next
(
info
,
info
->
s
->
keyinfo
+
inx
,
info
->
lastkey
,
info
->
lastkey_length
,
flag
,
SEARCH_BIGGER
,
info
->
s
->
state
.
key_root
[
inx
])))
break
;
}
...
...
myisam/mi_rprev.c
View file @
710b75f5
...
...
@@ -58,7 +58,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
/* Skip rows that are inserted by other threads since we got a lock */
if
((
error
=
_mi_search_next
(
info
,
share
->
keyinfo
+
inx
,
info
->
lastkey
,
info
->
lastkey_length
,
flag
,
SEARCH_SMALLER
,
share
->
state
.
key_root
[
inx
])))
break
;
}
...
...
myisam/mi_search.c
View file @
710b75f5
...
...
@@ -716,6 +716,7 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
{
alength
=
*
a
++
;
blength
=
*
b
++
;
end
=
a
+
alength
;
next_key_length
=
key_length
-
blength
-
1
;
}
else
{
...
...
myisam/myisamdef.h
View file @
710b75f5
...
...
@@ -622,6 +622,8 @@ void mi_dectivate_non_unique_index(MI_INFO *info, ha_rows rows);
int
_mi_rkey
(
MI_INFO
*
info
,
byte
*
buf
,
int
inx
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
search_flag
,
bool
raw_key
);
my_bool
check_table_is_closed
(
const
char
*
name
,
const
char
*
where
);
/* Functions needed by mi_check */
#ifdef __cplusplus
extern
"C"
{
...
...
scripts/make_binary_distribution.sh
View file @
710b75f5
...
...
@@ -48,7 +48,7 @@ rm $BASE/include/Makefile*; rm $BASE/include/*.in
cp
-p
tests/
*
.res tests/
*
.tst tests/
*
.pl
$BASE
/tests
cp
-p
support-files/
*
$BASE
/support-files
cp
-p
libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so
*
libmysql/libmysqlclient.
*
mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a
$BASE
/lib
cp
-p
libmysql/.libs/libmysqlclient.a libmysql/.libs/libmysqlclient.so
*
libmysql/libmysqlclient.
*
libmysql_r/.libs/libmysqlclient_a.a libmysql_r/.libs/libmysqlclient.so
*
libmysql_r/libmysqlclient.
*
mysys/libmysys.a strings/libmystrings.a dbug/libdbug.a
$BASE
/lib
cp
-r
-p
sql/share/
*
$BASE
/share/mysql
;
rm
-f
$BASE
/share/mysql/Makefile
*
$BASE
/share/mysql/
*
/
*
.OLD
$BASE
/share/CVS
$BASE
/share/
*
/CVS
cp
-p
scripts/
*
$BASE
/bin
...
...
sql/ha_heap.cc
View file @
710b75f5
...
...
@@ -251,6 +251,21 @@ int ha_heap::rename_table(const char * from, const char * to)
}
ha_rows
ha_heap
::
records_in_range
(
int
inx
,
const
byte
*
start_key
,
uint
start_key_len
,
enum
ha_rkey_function
start_search_flag
,
const
byte
*
end_key
,
uint
end_key_len
,
enum
ha_rkey_function
end_search_flag
)
{
KEY
*
pos
=
table
->
key_info
+
inx
;
if
(
start_key_len
!=
end_key_len
||
start_key_len
!=
pos
->
key_length
||
start_search_flag
!=
HA_READ_KEY_EXACT
||
end_search_flag
!=
HA_READ_KEY_EXACT
)
return
HA_POS_ERROR
;
// Can't only use exact keys
return
10
;
// Good guess
}
/* We can just delete the heap on creation */
int
ha_heap
::
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
)
...
...
sql/ha_heap.h
View file @
710b75f5
...
...
@@ -65,7 +65,10 @@ class ha_heap: public handler
int
reset
(
void
);
int
external_lock
(
THD
*
thd
,
int
lock_type
);
int
delete_all_rows
(
void
);
ha_rows
records_in_range
(
int
inx
,
const
byte
*
start_key
,
uint
start_key_len
,
enum
ha_rkey_function
start_search_flag
,
const
byte
*
end_key
,
uint
end_key_len
,
enum
ha_rkey_function
end_search_flag
);
int
delete_table
(
const
char
*
from
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
...
...
sql/handler.cc
View file @
710b75f5
...
...
@@ -317,8 +317,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
}
if
(
!
error
)
{
if
(
!
(
ref
=
(
byte
*
)
my_malloc
(
ALIGN_SIZE
(
ref_length
)
*
2
,
MYF
(
0
)
)))
if
(
!
(
ref
=
(
byte
*
)
alloc_root
(
&
table
->
mem_root
,
ALIGN_SIZE
(
ref_length
)
*
2
)))
{
close
();
error
=
HA_ERR_OUT_OF_MEM
;
...
...
sql/handler.h
View file @
710b75f5
...
...
@@ -200,7 +200,7 @@ class handler :public Sql_alloc
create_time
(
0
),
check_time
(
0
),
update_time
(
0
),
mean_rec_length
(
0
),
ft_handler
(
0
)
{}
virtual
~
handler
(
void
)
{
my_free
((
char
*
)
ref
,
MYF
(
MY_ALLOW_ZERO_PTR
));
}
virtual
~
handler
(
void
)
{}
int
ha_open
(
const
char
*
name
,
int
mode
,
int
test_if_locked
);
void
update_timestamp
(
byte
*
record
);
void
update_auto_increment
();
...
...
sql/lock.cc
View file @
710b75f5
...
...
@@ -407,15 +407,17 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
TABLE
*
table
;
char
key
[
MAX_DBKEY_LENGTH
];
uint
key_length
;
key_length
=
(
uint
)
(
strmov
(
strmov
(
key
,
table_list
->
db
)
+
1
,
table_list
->
name
)
-
key
)
+
1
;
DBUG_ENTER
(
"lock_table_name"
);
key_length
=
(
uint
)
(
strmov
(
strmov
(
key
,
table_list
->
db
)
+
1
,
table_list
->
name
)
-
key
)
+
1
;
/* Only insert the table if we haven't insert it already */
for
(
table
=
(
TABLE
*
)
hash_search
(
&
open_cache
,(
byte
*
)
key
,
key_length
)
;
table
;
table
=
(
TABLE
*
)
hash_next
(
&
open_cache
,(
byte
*
)
key
,
key_length
))
if
(
table
->
in_use
==
thd
)
return
0
;
DBUG_RETURN
(
0
)
;
/* Create a table entry with the right key and with an old refresh version */
/* Note that we must use my_malloc() here as this is freed by the table
...
...
@@ -423,17 +425,18 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
if
(
!
(
table
=
(
TABLE
*
)
my_malloc
(
sizeof
(
*
table
)
+
key_length
,
MYF
(
MY_WME
|
MY_ZEROFILL
))))
return
-
1
;
DBUG_RETURN
(
-
1
)
;
memcpy
((
table
->
table_cache_key
=
(
char
*
)
(
table
+
1
)),
key
,
key_length
);
table
->
key_length
=
key_length
;
table
->
in_use
=
thd
;
table
->
locked_by_name
=
1
;
table_list
->
table
=
table
;
if
(
hash_insert
(
&
open_cache
,
(
byte
*
)
table
))
return
-
1
;
DBUG_RETURN
(
-
1
)
;
if
(
remove_table_from_cache
(
thd
,
table_list
->
db
,
table_list
->
name
))
return
1
;
// Table is in use
return
0
;
DBUG_RETURN
(
1
)
;
// Table is in use
DBUG_RETURN
(
0
)
;
}
void
unlock_table_name
(
THD
*
thd
,
TABLE_LIST
*
table_list
)
...
...
@@ -446,7 +449,7 @@ static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
{
for
(
;
table_list
;
table_list
=
table_list
->
next
)
{
if
(
table_list
->
table
&&
table_is_used
(
table_list
->
table
))
if
(
table_list
->
table
&&
table_is_used
(
table_list
->
table
,
0
))
return
1
;
}
return
0
;
// All tables are locked
...
...
@@ -456,6 +459,7 @@ static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
bool
wait_for_locked_table_names
(
THD
*
thd
,
TABLE_LIST
*
table_list
)
{
bool
result
=
0
;
DBUG_ENTER
(
"wait_for_locked_table_names"
);
while
(
locked_named_table
(
thd
,
table_list
))
{
...
...
@@ -467,5 +471,5 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
wait_for_refresh
(
thd
);
pthread_mutex_lock
(
&
LOCK_open
);
}
return
result
;
DBUG_RETURN
(
result
)
;
}
sql/mini_client.cc
View file @
710b75f5
...
...
@@ -225,7 +225,8 @@ static void mc_free_old_query(MYSQL *mysql)
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
static
int
mc_sock_connect
(
File
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
)
static
int
mc_sock_connect
(
my_socket
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
)
{
#if defined(__WIN__)
return
connect
(
s
,
(
struct
sockaddr
*
)
name
,
namelen
);
...
...
@@ -451,7 +452,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
uint
port
,
const
char
*
unix_socket
,
uint
client_flag
)
{
char
buff
[
100
],
*
end
,
*
host_info
;
int
sock
;
my_socket
sock
;
ulong
ip_addr
;
struct
sockaddr_in
sock_addr
;
uint
pkt_length
;
...
...
sql/mysql_priv.h
View file @
710b75f5
...
...
@@ -319,10 +319,11 @@ TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
TABLE
*
find_locked_table
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
bool
reopen_table
(
TABLE
*
table
,
bool
locked
=
0
);
bool
reopen_tables
(
THD
*
thd
,
bool
get_locks
,
bool
in_refresh
);
void
close_old_data_files
(
THD
*
thd
,
TABLE
*
table
,
bool
abort_locks
);
void
close_old_data_files
(
THD
*
thd
,
TABLE
*
table
,
bool
abort_locks
,
bool
send_refresh
);
bool
close_data_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
bool
wait_for_tables
(
THD
*
thd
);
bool
table_is_used
(
TABLE
*
table
);
bool
table_is_used
(
TABLE
*
table
,
bool
wait_for_name_lock
);
bool
drop_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
void
abort_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
Field
*
find_field_in_tables
(
THD
*
thd
,
Item_field
*
item
,
TABLE_LIST
*
tables
);
...
...
sql/mysqld.cc
View file @
710b75f5
...
...
@@ -2407,6 +2407,12 @@ static void print_version(void)
server_version
,
SYSTEM_TYPE
,
MACHINE_TYPE
);
}
static
void
use_help
(
void
)
{
print_version
();
printf
(
"Use %s --help for a list of available options
\n
"
,
my_progname
);
}
static
void
usage
(
void
)
{
print_version
();
...
...
@@ -2621,7 +2627,7 @@ static void get_options(int argc,char **argv)
case
'O'
:
if
(
set_changeable_var
(
optarg
,
changeable_vars
))
{
us
age
();
us
e_help
();
exit
(
1
);
}
break
;
...
...
@@ -2666,7 +2672,8 @@ static void get_options(int argc,char **argv)
opt_noacl
=
1
;
else
{
usage
();
fprintf
(
stderr
,
"%s: Unrecognized option: %s
\n
"
,
my_progname
,
optarg
);
use_help
();
exit
(
1
);
}
break
;
...
...
@@ -2910,7 +2917,7 @@ static void get_options(int argc,char **argv)
default:
fprintf
(
stderr
,
"%s: Unrecognized option: %c
\n
"
,
my_progname
,
c
);
us
age
();
us
e_help
();
exit
(
1
);
}
}
...
...
@@ -2920,7 +2927,7 @@ static void get_options(int argc,char **argv)
if
(
argc
!=
optind
)
{
fprintf
(
stderr
,
"%s: Too many parameters
\n
"
,
my_progname
);
us
age
();
us
e_help
();
exit
(
1
);
}
fix_paths
();
...
...
sql/opt_range.cc
View file @
710b75f5
...
...
@@ -14,6 +14,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
TODO:
Fix that MAYBE_KEY are stored in the tree so that we can detect use
of full hash keys for queries like:
select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205);
*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
...
...
@@ -557,7 +567,7 @@ SEL_ARG *SEL_ARG::clone_tree()
** Returns:
** -1 if impossible select
** 0 if can't use quick_select
** 1 if found usabl
y
range
** 1 if found usabl
e
range
** Updates the following in the select parameter:
** needed_reg ; Bits for keys with may be used if all prev regs are read
** quick ; Parameter to use when reading records.
...
...
sql/sql_base.cc
View file @
710b75f5
...
...
@@ -582,9 +582,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
thd
->
mysys_var
->
current_cond
=
&
COND_refresh
;
thd
->
proc_info
=
"Flushing tables"
;
pthread_mutex_unlock
(
&
thd
->
mysys_var
->
mutex
);
VOID
(
pthread_cond_broadcast
(
&
COND_refresh
));
// If one flush is locked
close_old_data_files
(
thd
,
thd
->
open_tables
,
1
);
close_old_data_files
(
thd
,
thd
->
open_tables
,
1
,
1
);
bool
found
=
1
;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT
(
"info"
,
(
"Waiting for others threads to close their open tables"
));
...
...
@@ -921,7 +920,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
** There is a refresh in progress for this table
** Wait until the table is freed or the thread is killed.
*/
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
);
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
,
0
);
if
(
table
->
in_use
!=
thd
)
wait_for_refresh
(
thd
);
else
...
...
@@ -1216,9 +1215,11 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
abort_locks is set if called from flush_tables.
*/
void
close_old_data_files
(
THD
*
thd
,
TABLE
*
table
,
bool
abort_locks
)
void
close_old_data_files
(
THD
*
thd
,
TABLE
*
table
,
bool
abort_locks
,
bool
send_refresh
)
{
bool
found
=
0
;
DBUG_ENTER
(
"close_old_data_files"
);
bool
found
=
send_refresh
;
for
(;
table
;
table
=
table
->
next
)
{
if
(
table
->
version
!=
refresh_version
)
...
...
@@ -1241,6 +1242,7 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks)
}
if
(
found
)
VOID
(
pthread_cond_broadcast
(
&
COND_refresh
));
// Signal to refresh
DBUG_VOID_RETURN
;
}
...
...
@@ -1250,17 +1252,19 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks)
if the table is closed
*/
bool
table_is_used
(
TABLE
*
table
)
bool
table_is_used
(
TABLE
*
table
,
bool
wait_for_name_lock
)
{
do
{
char
*
key
=
table
->
table_cache_key
;
uint
key_length
=
table
->
key_length
;
for
(
TABLE
*
search
=
(
TABLE
*
)
hash_search
(
&
open_cache
,(
byte
*
)
key
,
key_length
)
;
for
(
TABLE
*
search
=
(
TABLE
*
)
hash_search
(
&
open_cache
,
(
byte
*
)
key
,
key_length
)
;
search
;
search
=
(
TABLE
*
)
hash_next
(
&
open_cache
,(
byte
*
)
key
,
key_length
))
{
if
(
search
->
locked_by_flush
||
search
->
locked_by_name
&&
wait_for_name_lock
||
search
->
db_stat
&&
search
->
version
<
refresh_version
)
return
1
;
// Table is used
}
...
...
@@ -1278,19 +1282,14 @@ bool wait_for_tables(THD *thd)
thd
->
proc_info
=
"Waiting for tables"
;
pthread_mutex_lock
(
&
LOCK_open
);
thd
->
some_tables_deleted
=
0
;
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
);
if
(
dropping_tables
)
{
(
void
)
pthread_cond_broadcast
(
&
COND_refresh
);
// Signal to refresh/delete
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
}
while
(
table_is_used
(
thd
->
open_tables
)
&&
!
thd
->
killed
)
while
(
!
thd
->
killed
)
{
thd
->
some_tables_deleted
=
0
;
close_old_data_files
(
thd
,
thd
->
open_tables
,
0
,
dropping_tables
!=
0
);
if
(
!
table_is_used
(
thd
->
open_tables
,
1
))
break
;
(
void
)
pthread_cond_wait
(
&
COND_refresh
,
&
LOCK_open
);
}
if
(
thd
->
killed
)
result
=
1
;
// aborted
else
...
...
sql/sql_parse.cc
View file @
710b75f5
...
...
@@ -1170,9 +1170,8 @@ mysql_execute_command(void)
#endif
case
SQLCOM_REPAIR
:
{
if
(
!
tables
->
db
)
tables
->
db
=
thd
->
db
;
if
(
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
res
=
mysql_repair_table
(
thd
,
tables
,
&
lex
->
check_opt
);
break
;
...
...
@@ -1695,6 +1694,10 @@ mysql_execute_command(void)
** Get the user (global) and database privileges for all used tables
** Returns true (error) if we can't get the privileges and we don't use
** table/column grants.
** The idea of EXTRA_ACL is that one will be granted access to the table if
** one has the asked privilege on any column combination of the table; For
** example to be able to check a table one needs to have SELECT privilege on
** any column of the table.
****************************************************************************/
bool
...
...
@@ -1760,7 +1763,8 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
TABLE_LIST
*
org_tables
=
tables
;
for
(;
tables
;
tables
=
tables
->
next
)
{
if
((
thd
->
master_access
&
want_access
)
==
want_access
&&
thd
->
db
)
if
((
thd
->
master_access
&
want_access
)
==
(
want_access
&
~
EXTRA_ACL
)
&&
thd
->
db
)
tables
->
grant
.
privilege
=
want_access
;
else
if
(
tables
->
db
&&
tables
->
db
==
thd
->
db
)
{
...
...
sql/sql_select.cc
View file @
710b75f5
...
...
@@ -800,6 +800,14 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
if
((
s
->
on_expr
=
tables
->
on_expr
))
{
// table->maybe_null=table->outer_join=1; // Mark for send fields
if
(
!
table
->
file
->
records
)
{
// Empty table
s
->
key_dependent
=
s
->
dependent
=
0
;
s
->
type
=
JT_SYSTEM
;
const_table_map
|=
table
->
map
;
set_position
(
join
,
const_count
++
,
s
,(
KEYUSE
*
)
0
);
continue
;
}
s
->
key_dependent
=
s
->
dependent
=
s
->
on_expr
->
used_tables
()
&
~
(
table
->
map
);
s
->
dependent
|=
stat_vector
[
i
-
1
]
->
dependent
|
table_vector
[
i
-
1
]
->
map
;
...
...
sql/table.h
View file @
710b75f5
...
...
@@ -91,6 +91,7 @@ struct st_table {
my_bool
crypted
;
my_bool
db_low_byte_first
;
/* Portable row format */
my_bool
locked_by_flush
;
my_bool
locked_by_name
;
Field
*
next_number_field
,
/* Set if next_number is activated */
*
found_next_number_field
,
/* Set on open */
*
rowid_field
;
...
...
tests/drop_test.pl
0 → 100755
View file @
710b75f5
#!/usr/bin/perl -w
#
# This is a test with uses processes to insert, select and drop tables.
#
$opt_loop_count
=
100000
;
# Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use
DBI
;
use
Getopt::
Long
;
use
Benchmark
;
package
main
;
$opt_skip_create
=
$opt_skip_in
=
$opt_verbose
=
$opt_fast_insert
=
$opt_lock_tables
=
$opt_debug
=
$opt_skip_delete
=
$opt_fast
=
$opt_force
=
0
;
$opt_host
=
"";
$opt_db
=
"
test
";
GetOptions
("
host=s
","
db=s
","
loop-count=i
","
skip-create
","
skip-in
","
skip-delete
",
"
verbose
","
fast-insert
","
lock-tables
","
debug
","
fast
","
force
")
||
die
"
Aborted
";
$opt_verbose
=
$opt_debug
=
$opt_lock_tables
=
$opt_fast_insert
=
$opt_fast
=
$opt_skip_in
=
$opt_force
=
undef
;
# Ignore warnings from these
print
"
Testing 5 multiple connections to a server with 1 insert, 2 drop/rename
\n
";
print
"
1 select and 1 flush thread
\n
";
$firsttable
=
"
bench_f1
";
####
#### Start timeing and start test
####
$start_time
=
new
Benchmark
;
if
(
!
$opt_skip_create
)
{
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$dbh
->
do
("
drop table if exists
$firsttable
,
${firsttable}
_1,
${firsttable}
_2
");
print
"
Creating table
$firsttable
in database
$opt_db
\n
";
$dbh
->
do
("
create table
$firsttable
(id int(6) not null, info varchar(32), marker char(1), primary key(id))
")
||
die
$
DBI::
errstr
;
$dbh
->
disconnect
;
$dbh
=
0
;
# Close handler
}
$|
=
1
;
# Autoflush
####
#### Start the tests
####
test_insert
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
insert
";
test_drop
(
1
)
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
drop 1
";
test_drop
(
2
)
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
drop 2
";
test_select
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
select
";
test_flush
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
flush
";
$errors
=
0
;
while
((
$pid
=
wait
())
!=
-
1
)
{
$ret
=
$?
/
256
;
print
"
thread '
"
.
$work
{
$pid
}
.
"
' finished with exit code
$ret
\n
";
$errors
++
if
(
$ret
!=
0
);
}
if
(
!
$opt_skip_delete
&&
!
$errors
)
{
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$dbh
->
do
("
drop table
$firsttable
");
$dbh
->
disconnect
;
$dbh
=
0
;
# Close handler
}
print
(
$errors
?
"
Test failed
\n
"
:"
Test ok
\n
");
$end_time
=
new
Benchmark
;
print
"
Total time:
"
.
timestr
(
timediff
(
$end_time
,
$start_time
),"
noc
")
.
"
\n
";
exit
(
0
);
#
# Insert records in the table
#
sub
test_insert
{
my
(
$dbh
,
$i
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
if
(
!
$dbh
->
do
("
insert into
$firsttable
values (
$i
,'This is entry
$i
','')
"))
{
print
"
Warning; Got error on insert:
"
.
$dbh
->
errstr
.
"
\n
"
if
(
!
(
$dbh
->
errstr
=~
/doesn't exist/
));
}
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_insert: Inserted
$i
rows
\n
";
exit
(
0
);
}
sub
test_drop
{
my
(
$id
)
=
@_
;
my
(
$dbh
,
$i
,
$sth
,
$error_counter
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$error_counter
=
0
;
$sleep_time
=
2
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
# Check if insert thread is ready
$sth
=
$dbh
->
prepare
("
select count(*) from
$firsttable
")
||
die
"
Got error on select from
$firsttable
:
$dbh
->errstr
\n
";
if
(
!
$sth
->
execute
||
!
(
@row
=
$sth
->
fetchrow_array
())
||
!
$row
[
0
])
{
$sth
->
finish
;
$sleep_time
=
1
;
last
if
(
$error_counter
++
==
5
);
next
;
}
$sleep_time
=
2
;
$sth
->
finish
;
# Change to use a new table
$dbh
->
do
("
create table
${firsttable}
_
$id
(id int(6) not null, info varchar(32), marker char(1), primary key(id))
")
||
die
$
DBI::
errstr
;
$dbh
->
do
("
drop table if exists
$firsttable
")
||
die
"
Got error on drop table:
$dbh
->errstr
\n
";
if
(
!
$dbh
->
do
("
alter table
${firsttable}
_
$id
rename to
$firsttable
"))
{
print
"
Warning; Got error from alter table:
"
.
$dbh
->
errstr
.
"
\n
"
if
(
!
(
$dbh
->
errstr
=~
/already exist/
));
$dbh
->
do
("
drop table if exists
${firsttable}
_
$id
")
||
die
"
Got error on drop table:
$dbh
->errstr
\n
";
}
}
$dbh
->
do
("
drop table if exists
$firsttable
,
${firsttable}
_
$id
")
||
die
"
Got error on drop table:
$dbh
->errstr
\n
";
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_drop: Did a drop
$i
times
\n
";
exit
(
0
);
}
#
# select records
#
sub
test_select
{
my
(
$dbh
,
$i
,
$sth
,
@row
,
$error_counter
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$error_counter
=
0
;
$sleep_time
=
3
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
$sth
=
$dbh
->
prepare
("
select sum(t.id) from
$firsttable
as t,
$firsttable
as t2
")
||
die
"
Got error on select:
$dbh
->errstr;
\n
";
if
(
$sth
->
execute
)
{
@row
=
$sth
->
fetchrow_array
();
$sth
->
finish
;
$sleep_time
=
3
;
}
else
{
print
"
Warning; Got error from select:
"
.
$dbh
->
errstr
.
"
\n
"
if
(
!
(
$dbh
->
errstr
=~
/doesn't exist/
));
$sth
->
finish
;
last
if
(
$error_counter
++
==
5
);
$sleep_time
=
1
;
}
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_select: ok
\n
";
exit
(
0
);
}
#
# flush records
#
sub
test_flush
{
my
(
$dbh
,
$i
,
$sth
,
@row
,
$error_counter
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$error_counter
=
0
;
$sleep_time
=
5
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
$sth
=
$dbh
->
prepare
("
select count(*) from
$firsttable
")
||
die
"
Got error on prepar:
$dbh
->errstr;
\n
";
if
(
$sth
->
execute
)
{
@row
=
$sth
->
fetchrow_array
();
$sth
->
finish
;
$sleep_time
=
5
;
$dbh
->
do
("
flush tables
$firsttable
")
||
die
"
Got error on flush table:
"
.
$dbh
->
errstr
.
"
\n
";
}
else
{
print
"
Warning; Got error from select:
"
.
$dbh
->
errstr
.
"
\n
"
if
(
!
(
$dbh
->
errstr
=~
/doesn't exist/
));
$sth
->
finish
;
last
if
(
$error_counter
++
==
5
);
$sleep_time
=
1
;
}
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_select: ok
\n
";
exit
(
0
);
}
tests/fork_test.pl
View file @
710b75f5
...
...
@@ -67,7 +67,7 @@ $errors=0;
while
((
$pid
=
wait
())
!=
-
1
)
{
$ret
=
$?
/
256
;
print
"
thread '
"
.
$work
{
$pid
}
.
"
' fin
n
ished with exit code
$ret
\n
";
print
"
thread '
"
.
$work
{
$pid
}
.
"
' finished with exit code
$ret
\n
";
$errors
++
if
(
$ret
!=
0
);
}
...
...
tests/rename_test.pl
0 → 100755
View file @
710b75f5
#!/usr/bin/perl -w
#
# This is a test with uses processes to insert, select and drop tables.
#
$opt_loop_count
=
100000
;
# Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use
DBI
;
use
Getopt::
Long
;
use
Benchmark
;
package
main
;
$opt_skip_create
=
$opt_skip_delete
=
$opt_skip_flush
=
0
;
$opt_host
=
"";
$opt_db
=
"
test
";
GetOptions
("
host=s
","
db=s
","
loop-count=i
","
skip-create
","
skip-delete
",
"
skip-flush
")
||
die
"
Aborted
";
print
"
Testing 5 multiple connections to a server with 1 insert, 1 rename
\n
";
print
"
1 select and 1 flush thread
\n
";
$firsttable
=
"
bench_f1
";
####
#### Start timing and start test
####
$start_time
=
new
Benchmark
;
if
(
!
$opt_skip_create
)
{
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$dbh
->
do
("
drop table if exists
$firsttable
,
${firsttable}
_1,
${firsttable}
_2
");
print
"
Creating table
$firsttable
in database
$opt_db
\n
";
$dbh
->
do
("
create table
$firsttable
(id int(6) not null, info varchar(32), marker char(1), primary key(id))
")
||
die
$
DBI::
errstr
;
$dbh
->
disconnect
;
$dbh
=
0
;
# Close handler
}
$|
=
1
;
# Autoflush
####
#### Start the tests
####
test_insert
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
insert
";
test_rename
(
1
)
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
rename 1
";
test_rename
(
2
)
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
rename 2
";
test_select
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
select
";
if
(
!
$opt_skip_flush
)
{
test_flush
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
flush
";
}
$errors
=
0
;
while
((
$pid
=
wait
())
!=
-
1
)
{
$ret
=
$?
/
256
;
print
"
thread '
"
.
$work
{
$pid
}
.
"
' finished with exit code
$ret
\n
";
$errors
++
if
(
$ret
!=
0
);
}
if
(
!
$opt_skip_delete
&&
!
$errors
)
{
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$dbh
->
do
("
drop table
$firsttable
");
$dbh
->
disconnect
;
$dbh
=
0
;
# Close handler
}
print
(
$errors
?
"
Test failed
\n
"
:"
Test ok
\n
");
$end_time
=
new
Benchmark
;
print
"
Total time:
"
.
timestr
(
timediff
(
$end_time
,
$start_time
),"
noc
")
.
"
\n
";
exit
(
0
);
#
# Insert records in the table. Delete table when test is finnished
#
sub
test_insert
{
my
(
$dbh
,
$i
,
$error
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
if
(
!
$dbh
->
do
("
insert into
$firsttable
values (
$i
,'This is entry
$i
','')
"))
{
$error
=
$dbh
->
errstr
;
$dbh
->
do
("
drop table
${firsttable}
");
# End other threads
die
"
Warning; Got error on insert:
"
.
$error
.
"
\n
";
}
}
sleep
(
1
);
$dbh
->
do
("
drop table
${firsttable}
")
||
die
"
Got error on drop table:
"
.
$dbh
->
errstr
.
"
\n
";
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_insert: Inserted
$i
rows
\n
";
exit
(
0
);
}
sub
test_rename
{
my
(
$id
)
=
@_
;
my
(
$dbh
,
$i
,
$error_counter
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$error_counter
=
0
;
$sleep_time
=
2
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
$dbh
->
do
("
create table
${firsttable}
_
$id
(id int(6) not null, info varchar(32), marker char(1), primary key(id))
")
||
die
$
DBI::
errstr
;
if
(
!
$dbh
->
do
("
rename table
$firsttable
to
${firsttable}
_
${id}
_1,
${firsttable}
_
$id
to
${firsttable}
"))
{
last
if
(
$dbh
->
errstr
=~
/^Can\'t find/
);
die
"
Got error on rename:
"
.
$dbh
->
errstr
.
"
\n
";
}
$dbh
->
do
("
drop table
${firsttable}
_
${id}
_1
")
||
die
"
Got error on drop table:
"
.
$dbh
->
errstr
.
"
\n
";
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_drop: Did a drop
$i
times
\n
";
exit
(
0
);
}
#
# select records
#
sub
test_select
{
my
(
$dbh
,
$i
,
$sth
,
@row
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$sleep_time
=
3
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
$sth
=
$dbh
->
prepare
("
select sum(t.id) from
$firsttable
as t,
$firsttable
as t2
")
||
die
"
Got error on select:
$dbh
->errstr;
\n
";
if
(
$sth
->
execute
)
{
@row
=
$sth
->
fetchrow_array
();
$sth
->
finish
;
}
else
{
$sth
->
finish
;
last
if
(
!
(
$dbh
->
errstr
=~
/doesn\'t exist/
));
die
"
Got error on select:
"
.
$dbh
->
errstr
.
"
\n
";
}
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_select: ok
\n
";
exit
(
0
);
}
#
# flush records
#
sub
test_flush
{
my
(
$dbh
,
$i
,
$sth
,
@row
,
$error_counter
,
$sleep_time
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$error_counter
=
0
;
$sleep_time
=
5
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
sleep
(
$sleep_time
);
$sth
=
$dbh
->
prepare
("
select count(*) from
$firsttable
")
||
die
"
Got error on prepar:
$dbh
->errstr;
\n
";
if
(
$sth
->
execute
)
{
@row
=
$sth
->
fetchrow_array
();
$sth
->
finish
;
$sleep_time
=
5
;
$dbh
->
do
("
flush tables
$firsttable
")
||
die
"
Got error on flush table:
"
.
$dbh
->
errstr
.
"
\n
";
}
else
{
last
if
(
!
(
$dbh
->
errstr
=~
/doesn\'t exist/
));
die
"
Got error on flush:
"
.
$dbh
->
errstr
.
"
\n
";
}
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_select: ok
\n
";
exit
(
0
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment