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
89ef355b
Commit
89ef355b
authored
Jan 08, 2003
by
monty@mashka.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix for bug in LOAD DATA INFILE and replication
Fix for SHOW VARIABLES in embedded server
parent
602f3664
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
129 additions
and
15 deletions
+129
-15
Docs/internals.texi
Docs/internals.texi
+72
-1
configure.in
configure.in
+1
-1
sql/log_event.cc
sql/log_event.cc
+51
-5
sql/log_event.h
sql/log_event.h
+3
-2
sql/slave.cc
sql/slave.cc
+0
-6
sql/sql_show.cc
sql/sql_show.cc
+2
-0
No files found.
Docs/internals.texi
View file @
89ef355b
...
...
@@ -96,13 +96,84 @@ cached for each user/database combination.
Many use of @code
{
GROUP BY
}
or @code
{
DISTINCT
}
caches all found rows in
a @code
{
HEAP
}
table. (This is a very quick in-memory table with hash index.)
@item Join
Row
Cache
@item Join
buffer
Cache
For every full join in a @code
{
SELECT
}
statement (a full join here means
there were no keys that one could use to find the next table in a list),
the found rows are cached in a join cache. One @code
{
SELECT
}
query can
use many join caches in the worst case.
@end table
@node join
_
buffer
_
size, flush tables, caching, Top
@subchapter How MySQL uses the join
_
buffer cache
Basic information about @code
{
join
_
buffer
_
size
}
:
@itemize @bullet
@item
It's only used in the case when join type is of type @code
{
ALL
}
or
@code
{
index
}
; In other words: no possible keys can be used.
@item
A join buffer is never allocated for the first not-const table,
even it it would be of type @code
{
ALL
}
/@code
{
index
}
.
@item
The buffer is allocated when we need to do a each full join between two
tables and freed after the query is done.
@item
Accepted row combinations of tables before the @code
{
ALL
}
/@code
{
index
}
able is stored in the cache and is used to compare against each read
row in the @code
{
ALL
}
table.
@item
We only store the used fields in the join
_
buffer cache, not the
whole rows.
@end itemize
Assume you have the following join:
@example
Table name Type
t1 range
t2 ref
t3 @code
{
ALL
}
@end example
The join is then done as follows:
@example
- While rows in t1 matching range
- Read through all rows in t2 according to reference key
- Store used fields form t1,t2 in cache
- If cache is full
- Read through all rows in t3
- Compare t3 row against all t1,t2 combination in cache
- If rows satisfying join condition, send it to client
- Empty cache
- Read through all rows in t3
- Compare t3 row against all stored t1,t2 combinations in cache
- If rows satisfying join condition, send it to client
@end example
The above means that table t3 is scanned
@example
(size-of-stored-row(t1,t2) * accepted-row-cominations(t1,t2))/
join
_
buffer
_
size+1
@end example
times.
Some conclusions:
@itemize @bullet
@item
The larger the join
_
buff
_
size, the fewer scans of t3.
If @code
{
join
_
buff
_
size
}
is already large enough to hold all previous row
combinations then there is no speed to gain by making it bigger.
@item
If there is several tables of @code
{
ALL
}
/@code
{
index
}
then the we
allocate one @code
{
join
_
buffer
_
size buffer
}
for each of them and use the
same algorithm described above to handle it. (In other words, we store
the same row combination several times into different buffers)
@end itemize
@node flush tables, filesort, caching, Top
@chapter How MySQL Handles @code
{
FLUSH TABLES
}
...
...
configure.in
View file @
89ef355b
...
...
@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT
(
sql/mysqld.cc
)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE
(
mysql, 4.0.
8
-gamma
)
AM_INIT_AUTOMAKE
(
mysql, 4.0.
9
-gamma
)
AM_CONFIG_HEADER
(
config.h
)
PROTOCOL_VERSION
=
10
...
...
sql/log_event.cc
View file @
89ef355b
...
...
@@ -206,7 +206,19 @@ Log_event::Log_event(const char* buf, bool old_format)
int
Log_event
::
exec_event
(
struct
st_relay_log_info
*
rli
)
{
if
(
rli
)
// QQ When is this not true ?
/*
rli is null when (as far as I (Guilhem) know)
the caller is
Load_log_event::exec_event *and* that one is called from
Execute_load_log_event::exec_event.
In this case, we don't do anything here ;
Execute_load_log_event::exec_event will call Log_event::exec_event
again later with the proper rli.
Strictly speaking, if we were sure that rli is null
only in the case discussed above, 'if (rli)' is useless here.
But as we are not 100% sure, keep it for now.
*/
if
(
rli
)
{
if
(
rli
->
inside_transaction
)
rli
->
inc_pending
(
get_event_len
());
...
...
@@ -1773,8 +1785,34 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
return
Log_event
::
exec_event
(
rli
);
}
/*
Does the data loading job when executing a LOAD DATA on the slave
SYNOPSIS
Load_log_event::exec_event
net
rli
use_rli_only_for_errors - if set to 1, rli is provided to
Load_log_event::exec_event only for this
function to have RPL_LOG_NAME and
rli->last_slave_error, both being used by
error reports. rli's position advancing
is skipped (done by the caller which is
Execute_load_log_event::exec_event).
- if set to 0, rli is provided for full use,
i.e. for error reports and position
advancing.
DESCRIPTION
Does the data loading job when executing a LOAD DATA on the slave
RETURN VALUE
0 Success
1 Failure
*/
int
Load_log_event
::
exec_event
(
NET
*
net
,
struct
st_relay_log_info
*
rli
)
int
Load_log_event
::
exec_event
(
NET
*
net
,
struct
st_relay_log_info
*
rli
,
bool
use_rli_only_for_errors
)
{
init_sql_alloc
(
&
thd
->
mem_root
,
8192
,
0
);
thd
->
db
=
rewrite_db
((
char
*
)
db
);
...
...
@@ -1836,8 +1874,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
TL_WRITE
))
thd
->
query_error
=
1
;
if
(
thd
->
cuted_fields
)
/*
log_pos is the position of the LOAD
event in the master log
*/
sql_print_error
(
"Slave: load data infile at position %s in log \
'%s' produced %d warning(s)"
,
llstr
(
rli
->
master_log_pos
,
llbuff
),
RPL_LOG_NAME
,
'%s' produced %d warning(s)"
,
llstr
(
log_pos
,
llbuff
),
RPL_LOG_NAME
,
thd
->
cuted_fields
);
if
(
net
)
net
->
pkt_nr
=
thd
->
net
.
pkt_nr
;
...
...
@@ -1877,7 +1919,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
return
1
;
}
return
Log_event
::
exec_event
(
rli
);
return
(
use_rli_only_for_errors
?
0
:
Log_event
::
exec_event
(
rli
)
);
}
...
...
@@ -2132,7 +2174,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
save_options
=
thd
->
options
;
thd
->
options
&=
~
(
ulong
)
(
OPTION_BIN_LOG
);
lev
->
thd
=
thd
;
if
(
lev
->
exec_event
(
0
,
0
))
/*
lev->exec_event should use rli only for errors
i.e. should not advance rli's position
*/
if
(
lev
->
exec_event
(
0
,
rli
,
1
))
{
slave_print_error
(
rli
,
my_errno
,
"Failed executing load from '%s'"
,
fname
);
thd
->
options
=
save_options
;
...
...
sql/log_event.h
View file @
89ef355b
...
...
@@ -417,9 +417,10 @@ class Load_log_event: public Log_event
const
char
*
get_db
()
{
return
db
;
}
int
exec_event
(
struct
st_relay_log_info
*
rli
)
{
return
exec_event
(
thd
->
slave_net
,
rli
);
return
exec_event
(
thd
->
slave_net
,
rli
,
0
);
}
int
exec_event
(
NET
*
net
,
struct
st_relay_log_info
*
rli
);
int
exec_event
(
NET
*
net
,
struct
st_relay_log_info
*
rli
,
bool
use_rli_only_for_errors
);
#else
void
print
(
FILE
*
file
,
bool
short_form
=
0
,
char
*
last_db
=
0
);
#endif
...
...
sql/slave.cc
View file @
89ef355b
...
...
@@ -2343,12 +2343,6 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
memcpy
(
mi
->
master_log_name
,
rev
->
new_log_ident
,
rev
->
ident_len
+
1
);
mi
->
master_log_pos
=
rev
->
pos
;
pthread_mutex_lock
(
&
mi
->
rli
.
data_lock
);
memcpy
(
mi
->
rli
.
master_log_name
,
rev
->
new_log_ident
,
rev
->
ident_len
+
1
);
mi
->
rli
.
master_log_pos
=
rev
->
pos
;
pthread_mutex_unlock
(
&
mi
->
rli
.
data_lock
);
DBUG_PRINT
(
"info"
,
(
"master_log_pos: '%s' %d"
,
mi
->
master_log_name
,
(
ulong
)
mi
->
master_log_pos
));
#ifndef DBUG_OFF
...
...
sql/sql_show.cc
View file @
89ef355b
...
...
@@ -1217,6 +1217,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
case
SHOW_RPL_STATUS
:
net_store_data
(
&
packet2
,
rpl_status_type
[(
int
)
rpl_status
]);
break
;
#ifndef EMBEDDED_LIBRARY
case
SHOW_SLAVE_RUNNING
:
{
LOCK_ACTIVE_MI
;
...
...
@@ -1226,6 +1227,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
UNLOCK_ACTIVE_MI
;
break
;
}
#endif
case
SHOW_OPENTABLES
:
net_store_data
(
&
packet2
,(
uint32
)
cached_tables
());
break
;
...
...
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