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
178f8e91
Commit
178f8e91
authored
Jan 17, 2001
by
sasha@mysql.sashanet.com
Browse files
Options
Browse Files
Download
Plain Diff
semi-manual merge, some more needs to be fixed in mysqltest.c in fully
manual mode
parents
03090462
2ae124db
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
529 additions
and
119 deletions
+529
-119
.bzrignore
.bzrignore
+1
-0
Docs/manual.texi
Docs/manual.texi
+167
-44
client/mysql.cc
client/mysql.cc
+8
-4
client/mysqltest.c
client/mysqltest.c
+58
-2
mysql-test/mysql-test-run.sh
mysql-test/mysql-test-run.sh
+13
-3
mysql-test/r/rpl000001.result
mysql-test/r/rpl000001.result
+5
-0
mysql-test/r/rpl000014.result
mysql-test/r/rpl000014.result
+4
-4
mysql-test/t/rpl000001.test
mysql-test/t/rpl000001.test
+7
-4
mysql-test/t/rpl000002.test
mysql-test/t/rpl000002.test
+6
-1
mysql-test/t/rpl000003.test
mysql-test/t/rpl000003.test
+6
-1
mysql-test/t/rpl000004.test
mysql-test/t/rpl000004.test
+7
-0
mysql-test/t/rpl000005.test
mysql-test/t/rpl000005.test
+5
-1
mysql-test/t/rpl000006.test
mysql-test/t/rpl000006.test
+3
-0
mysql-test/t/rpl000007.test
mysql-test/t/rpl000007.test
+5
-1
mysql-test/t/rpl000008.test
mysql-test/t/rpl000008.test
+6
-1
mysql-test/t/rpl000009.test
mysql-test/t/rpl000009.test
+9
-2
mysql-test/t/rpl000010.test
mysql-test/t/rpl000010.test
+5
-1
mysql-test/t/rpl000011.test
mysql-test/t/rpl000011.test
+7
-2
mysql-test/t/rpl000012.test
mysql-test/t/rpl000012.test
+7
-2
mysql-test/t/rpl000013.test
mysql-test/t/rpl000013.test
+11
-9
mysql-test/t/rpl000014.test
mysql-test/t/rpl000014.test
+7
-3
mysql-test/t/rpl000015.test
mysql-test/t/rpl000015.test
+6
-1
mysql-test/t/rpl000016.test
mysql-test/t/rpl000016.test
+6
-3
sql/item_create.cc
sql/item_create.cc
+5
-0
sql/item_create.h
sql/item_create.h
+1
-0
sql/item_func.cc
sql/item_func.cc
+23
-0
sql/item_func.h
sql/item_func.h
+12
-0
sql/lex.h
sql/lex.h
+2
-0
sql/slave.cc
sql/slave.cc
+56
-2
sql/slave.h
sql/slave.h
+6
-0
sql/sql_class.h
sql/sql_class.h
+19
-0
sql/sql_repl.cc
sql/sql_repl.cc
+46
-28
No files found.
.bzrignore
View file @
178f8e91
...
...
@@ -188,3 +188,4 @@ Docs/my_sys.doc
tmp/*
extra/resolve_stack_dump
sql/share/*.sys
BitKeeper/tmp/bkr3sAHD
Docs/manual.texi
View file @
178f8e91
...
...
@@ -17401,6 +17401,17 @@ Addresses may be 4 or 8 byte addresses:
mysql> select INET_ATON("209.207.224.40");
-> 3520061480
@end example
@findex MASTER_POS_WAIT()
@item MASTER_POS_WAIT(log_name, log_pos)
Blocks until the slave reaches the specified position in the master log during
replication. If master information is not initialized, returns NULL. If the
slave is not running, will block and wait until it is started and goes to or
past
the specified postion. If the slave is already past the specified postion,
returns immediately. The return value is the number of log events it had to
wait to get to the specified position, or NULL in case of error. Useful for
control of master-slave synchronization, but was originally written to
facilate replication testing.
@end table
@findex GROUP BY functions
...
...
@@ -25618,6 +25629,7 @@ tables}.
* Replication Options:: Replication Options in my.cnf
* Replication SQL:: SQL Commands related to replication
* Replication FAQ:: Frequently Asked Questions about replication
* Troubleshooting Replication:: Troubleshooting Replication
@end menu
@node Replication Intro, Replication Implementation, Replication, Replication
...
...
@@ -25634,7 +25646,7 @@ Starting in Version 3.23.15, @strong{MySQL} supports one-way replication
internally. One server acts as the master, while the other acts as the
slave. Note that one server could play the roles of master in one pair
and slave in the other. The master server keeps a binary log of updates
(@xref{Binary log}.) and an index file
of
binary logs to keep track of
(@xref{Binary log}.) and an index file
to
binary logs to keep track of
log rotation. The slave, upon connecting, informs the master where it
left off since the last successfully propagated update, catches up on
the updates, and then blocks and waits for the master to notify it of
...
...
@@ -25656,7 +25668,7 @@ master. @xref{Backup}.
@strong{MySQL} replication is based on the server keeping track of all
changes to your database (updates, deletes, etc) in the binary
log
(@xref{Binary log}.),
and the slave server(s) reading the saved
log
. (@xref{Binary log}.)
and the slave server(s) reading the saved
queries from the master server's binary log so that the slave can
execute the same queries on its copy of the data.
...
...
@@ -25668,9 +25680,11 @@ logging on the master. If you start your slaves with data that doesn't
agree with what was on the master @strong{when the binary log was
started}, your slaves may fail.
A future
Version of @strong{MySQL} is planned
remove the need to keep a
A future
version (4.0) of @strong{MySQL} will
remove the need to keep a
(possibly large) snapshot of data for new slaves that you might wish to
set up.
set up through the live backup functionality with no locking required.
However, at this time, it is necessary to block all writes either with a
global read lock or by shutting down the master while taking a snapshot.
Once a slave is properly configured and running, it will simply connect
to the master and wait for updates to process. If the master goes away
...
...
@@ -25690,20 +25704,20 @@ The next section explains the master/slave setup process in more detail.
Below is a quick description of how to set up complete replication on
your current @strong{MySQL} server. It assumes you want to replicate all
your databases and have not configured replication before. You will need
to shutdown your master server briefly to complete the steps outlined
to shutdown your master server briefly to complete the ste
o
ps outlined
below.
@enumerate
@item
Make
sure you have a recent version of @strong{MySQL} installed on the
master
and slave(s).
Make
you have a recent version of @strong{MySQL} installed on the master
and slave(s).
Use Version 3.23.29 or higher. Previous releases used a different binary
log format and had bugs which have been fixed in newer releases. Please
log format and had bugs which have been fixed in newer releases. Please
,
do not report bugs until you have verified that the problem is present
in the latest release.
@item
Set up
a special
replication user on the master with the @code{FILE}
Set up
special a
replication user on the master with the @code{FILE}
privilege and permission to connect from all the slaves. If the user is
only doing replication (which is recommended), you don't need to grant any
additional privileges.
...
...
@@ -25726,7 +25740,7 @@ mysqladmin -u root -p<password> shutdown
Snapshot all the data on your master server.
The easiest way to do this (on Unix) is to simply use @strong{tar} to
produce an arch
iv
e of your entrie data directory. The exact data
produce an arch
vi
e of your entrie data directory. The exact data
directory location depends on your installation.
@example
...
...
@@ -25738,8 +25752,11 @@ the data directory.
@item
In @code{my.cnf} on the master add @code{log-bin} and
@code{server-id=<some unique number>} to the @code{[mysqld]} section.
@code{server-id=unique number} to the @code{[mysqld]} section and
restart it. It is very important that the id of the slave is different from
the id of the master. Think of @code{server-id} as something similar
to the IP address - it uniquely identifies the server instance in the
comminity of replication partners.
@example
[mysqld]
...
...
@@ -25764,7 +25781,12 @@ replacing the values in <> with what is relevant to your system.
@code{server-id} must be different for each server participating in
replication. If you don't specify a server-id, it will be set to 1 if
you have not defined @code{master-host}, else it will be set to 2.
you have not defined @code{master-host}, else it will be set to 2. Note
that in the case of @code{server-id} omission the master will refuse
connections from all slaves, and the slave will refuse to connect to a
master. Thus, omitting @code{server-id} is only good for backup with a
binary log.
@item
Copy the snapshot data into your data directory on your slave(s). Make
...
...
@@ -25794,10 +25816,11 @@ If a slave is not able to replicate for any reason, you will find error
messages in the error log on the slave.
Once a slave is replicating, you will find a file called
@code{master.info} in the same directory as your error log.
The
@code{master.info} in the same directory as your error log. The
@code{master.info} file is used by the slave to keep track of how much
of the master's binary log it has processed. @strong{Do not} remove or
edit this file.
of the master's binary log is has processed. @strong{Do not} remove or
edit the file, unless you really know what you are doing. Even in that case,
it is preferred that you use @code{CHANGE MASTER TO} command.
@cindex options, replication
@cindex @code{my.cnf} file
...
...
@@ -25812,20 +25835,16 @@ Below is an explanation of what is supported and what is not:
Replication will be done correctly with @code{AUTO_INCREMENT},
@code{LAST_INSERT_ID}, and @code{TIMESTAMP} values.
@item
@code{RAND()} in updates does not replicate properly. Use
@code{RAND(some_non_rand_expr)} if you are replcating updates with
@code{RAND()}. You can, for example, use @code{UNIX_TIMESTAMP()} for the
argument to @code{RAND()}.
@item
@code{LOAD DATA INFILE} will be handled properly as long as the file
still resides on the master server at the time of update
propagation. @code{LOAD LOCAL DATA INFILE} will be skipped.
@item
The master and slave is not synchronizing @code{RAND()}. This means
that you should not use @code{RAND()} with any statement that updates a
table. As fixing this will require a change in the protocol, we will
delay fixing this until 4.0. A workaround is using @code{RAND(#)}, where
# is a random integer genearated by your application or by first
executing @code{LAST_INSERT_ID(RAND())} and then using
@code{LAST_INSERT_ID()} in the next statement.
@item
Update queries that use user variables (@code{@@variable}) are not yet
replication-safe.
Update queries that use user variables are not replication-safe (yet).
@item
Temporary tables starting in 3.23.29 are replicated properly with the
exception of the case when you shut down slave server ( not just slave thread),
...
...
@@ -25892,15 +25911,17 @@ Starting in Version 3.23.19, you can clean up stale replication leftovers when
something goes wrong and you want a clean start with @code{FLUSH MASTER}
and @code{FLUSH SLAVE} commands. In Version 3.23.26 we have renamed them to
@code{RESET MASTER} and @code{RESET SLAVE} respectively to clarify
what they do. The old @code{FLUSH} variants still work, though for
what they do. The old @code{FLUSH} variants still work, though
,
for
compatibility.
@item
Starting in Version 3.23.21, you can use @code{LOAD TABLE FROM MASTER} for
network backup and to set up replication initially.
network backup and to set up replication initially. We have recently
received a number of bug reports concerning it that we are investigating, so
we recommend that you use it only in testing until we make it more stable.
@item
Starting in Version 3.23.23, you can change masters
with @code{CHANGE MASTER
TO}.
Starting in Version 3.23.23, you can change masters
and adjust log position
with @code{CHANGE MASTER
TO}.
@item
Starting in Version 3.23.23, you tell the master that updates in certain
databases should not be logged to the binary log with @code{binlog-ignore-db}.
...
...
@@ -25916,7 +25937,7 @@ to get rid of old logs while the slave is running.
@node Replication Options, Replication SQL, Replication Features, Replication
@section Replication Options in my.cnf
If you are using replication, we recommend you to use MySQL Version 3.23.
28
or
If you are using replication, we recommend you to use MySQL Version 3.23.
30
or
later. Older versions work, but they do have some bugs and are missing some
features.
...
...
@@ -26169,8 +26190,8 @@ last log on the list), backup all the logs you are about to delete
@end multitable
@node Replication FAQ,
, Replication SQL, Replication
@section
Frequently Asked Questions about replication
@node Replication FAQ,
Troubleshooting Replication
, Replication SQL, Replication
@section
Replication FAQ
@cindex @code{Binlog_Dump}
@strong{Q}: Why do I sometimes see more than one @code{Binlog_Dump} thread on
...
...
@@ -26227,11 +26248,10 @@ the slave can stay down for some time - since the master is logging
all the updates, the slave will be able to catch up once it is up and
can connect.
We plan to make post 3.23.26 versions to be backwards compatible
for replication down to Version 3.23.26, so upgrade should be just a matter
of plug and play. Of course, as one joke goes, plug and play works
usually only 50% of the time - just the plug part. We hope to do much
better than that, though.
After 3.23.26, we have locked the replication protocol for modifications, so
you can upgrade masters and slave on the fly to a newer 3.23 version and you
can have different versions of @code{MySQL} running on the slave and the
master, as long as they are both newer than 3.23.26.
@cindex replication, two-way
@strong{Q}: What issues should I be aware of when setting up two-way
...
...
@@ -26251,10 +26271,6 @@ two-way replication relationship, unless you are sure that you updates
can safely happen in any order, or unless you take care of mis-ordered
updates somehow in the client code.
Until we implement @code{server_id} variable, you cannot have more than
two servers in a co-master replication relationship, and you must
run @code{mysqld} without @code{log-slave-updates} (default) to avoid
infinite update loops.
You must also realize that two-way replication actually does not improve
performance very much, if at all, as far as updates are concerned. Both
...
...
@@ -26365,7 +26381,7 @@ to all servers)
So if N = 0, which means we have no replication, our system can handle
1200/11, about 109 writes per second (which means we will have 9 times
as many reads to the nature of our application).
as many reads
due
to the nature of our application).
If N = 1, we can get up to 184 writes per second.
...
...
@@ -26428,6 +26444,105 @@ We are currently working on intergrating an automatic master election
system into @strong{MySQL}, but until it is ready, you will have to
create your own monitoring tools.
@node Troubleshooting Replication, ,Replication FAQ, Replication
@section Troubleshooting Replication
If you have followed the instructions, and your replication setup is not
working, first elliminate the user error factor by checking the following:
@itemize @bullet
@item
Is the master logging to the binary log? Check with @code{SHOW MASTER STATUS}.
If it is, @code{Position} will be non-zero. If not, verify that you have
given the master @code{log-bin} option and have set @code{server-id}.
@item
Is the slave running? Check with @code{SHOW SLAVE STATUS}. The answer is found
in @code{Slave_running} column. If not, verify slave options and check the
error log for messages.
@item
If the slave is running, did it establish connection with the master? Do
@code{SHOW PROCESSLIST}, find the thread with @code{system user} value in
@code{User} column and @code{none} in the @code{Host} column, and check the
@code{State} column. If it says @code{connecting to master}, verify the
privileges for the replication user on the master, master host name, your
DNS setup, whether the master is actually running, whether it is reachable
from the slave, and if all that seems ok, read the error logs.
@item
If the slave was running, but then stopped, check the error logs. It usually
happens when some query that succeeded on the master fails on the slave. This
should never happen if you have taken a proper snapshot of the master, and
never modify the data on the slave outside of the slave thread. If it does,
it is a bug, read below on how to report it.
@item
Make sure you are not running into an old bug by upgrading to the most recent
version.
@item
If all else fails, read the error logs. If they are big,
@code{grep -i slave /path/to/your-log.err} on the slave. There is no
generic pattern to search for on the master, as the only errors it logs
are general system errors - if it can, it will send the error to the slave
when things go wrong.
@end itemize
When you have determined that there is no user error involved, and replication
still either does not work at all or is unstable, it is time to start working
on a bug report. We need to get as much info as possible from you to be able
to track down the bug. Please do spend some time and effort preparing a good
bug report. Ideally, we would like to have a test case in the format found in
@code{mysql-test/t/rpl*} directory of the source tree. If you submit a test
case like that, you can expect a patch within a day or two in most cases,
although, of course, you mileage may vary depending on a number of factors.
Second best option is a just program with easily configurable connection
arguments for the master and the slave that will demonstrate the problem on our
systems. You can write one in Perl or in C, depending on which language you
know better.
If you have one of the above ways to demonstrate the bug, use
@code{mysqlbug} to prepare a bug report and send it to
@email{bugs@@lists.mysql.com}. If you have a phantom - a problem that
does occur but you cannot duplicate "at will":
@itemize @bullet
@item
Verify that there is no user error involved. For example, if you update the
slave outside of the slave thread, the data will be out of sync, and you can
have unique key violations on updates, in which case the slave thread will
stop and wait for you to clean up the tables manually to bring them in sync.
@item
Run slave with @code{log-slave-updates} and @code{log-bin} - this will keep
a log of all updates on the slave.
@item
Save all evidence before reseting the replication. If we have no or only
sketchy information, it would take us a while to track down the problem. The
evidence you should collect is:
@itemize @bullet
@item
all binary logs on the master
@item
all binary log on the slave
@item
the output of @code{SHOW MASTER STATUS} on the master at the time
you have discovered the problem
@item
the output of @code{SHOW SLAVE STATUS} on the master at the time
you have discovered the problem
@item
Error logs on the master and on the slave
@end itemize
@item
Use @code{mysqlbinlog} to examine the binary logs. The following should
be helpful
to find the trouble query, for example:
@example
mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head
@end example
@end itemize
Once you have collected the evidence on the phantom problem, try hard to
isolate it into a separate test case first. Then report the problem to
@email{bugs@@lists.mysql.com} with as much info as possible.
@cindex performance, maximizing
@cindex optimization
...
...
@@ -40439,6 +40554,7 @@ version. The replication and BerkeleyDB code is still under development,
though, so Version 3.23 is not released as a stable version yet.
@menu
* News-3.23.32:: Changes in release 3.23.32
* News-3.23.31:: Changes in release 3.23.31
* News-3.23.30:: Changes in release 3.23.30
* News-3.23.29:: Changes in release 3.23.29
...
...
@@ -40473,7 +40589,14 @@ though, so Version 3.23 is not released as a stable version yet.
* News-3.23.0:: Changes in release 3.23.0
@end menu
@node News-3.23.31, News-3.23.30, News-3.23.x, News-3.23.x
@node News-3.23.32, News-3.23.31, News-3.23.x, News-3.23.x
@appendixsubsec Changes in release 3.23.32
@itemize @bullet
@item
Added MASTER_POS_WAIT()
@end itemize
@node News-3.23.31, News-3.23.30, News-3.23.32, News-3.23.x
@appendixsubsec Changes in release 3.23.31
@itemize @bullet
@item
client/mysql.cc
View file @
178f8e91
...
...
@@ -125,6 +125,7 @@ static char *current_host,*current_db,*current_user=0,*opt_password=0,
*
default_charset
;
static
char
*
histfile
;
static
String
glob_buffer
,
old_buffer
;
static
int
wait_time
=
5
;
static
STATUS
status
;
static
ulong
select_limit
,
max_join_size
,
opt_connect_timeout
=
0
;
static
char
default_pager
[
FN_REFLEN
];
...
...
@@ -427,7 +428,7 @@ static struct option long_options[] =
{
"verbose"
,
no_argument
,
0
,
'v'
},
{
"version"
,
no_argument
,
0
,
'V'
},
{
"vertical"
,
no_argument
,
0
,
'E'
},
{
"wait"
,
no
_argument
,
0
,
'w'
},
{
"wait"
,
optional
_argument
,
0
,
'w'
},
{
0
,
0
,
0
,
0
}
};
...
...
@@ -560,7 +561,7 @@ static int get_options(int argc, char **argv)
set_all_changeable_vars
(
changeable_vars
);
while
((
c
=
getopt_long
(
argc
,
argv
,
"?ABCD:LfgGHinNoqrstTU::vVwWEe:h:O:P:S:u:#::p::"
,
"?ABCD:LfgGHinNoqrstTU::vVw
::
WEe:h:O:P:S:u:#::p::"
,
long_options
,
&
option_index
))
!=
EOF
)
{
switch
(
c
)
{
...
...
@@ -664,7 +665,10 @@ static int get_options(int argc, char **argv)
case
'n'
:
unbuffered
=
1
;
break
;
case
'v'
:
verbose
++
;
break
;
case
'E'
:
vertical
=
1
;
break
;
case
'w'
:
wait_flag
=
1
;
break
;
case
'w'
:
wait_flag
=
1
;
if
(
optarg
)
wait_time
=
atoi
(
optarg
)
;
break
;
case
'A'
:
no_rehash
=
1
;
break
;
case
'G'
:
no_named_cmds
=
0
;
break
;
case
'g'
:
no_named_cmds
=
1
;
break
;
...
...
@@ -2114,7 +2118,7 @@ sql_connect(char *host,char *database,char *user,char *password,uint silent)
message
=
1
;
tee_fputs
(
"Waiting"
,
stderr
);
(
void
)
fflush
(
stderr
);
}
(
void
)
sleep
(
5
);
(
void
)
sleep
(
wait_time
);
if
(
!
silent
)
{
putc
(
'.'
,
stderr
);
(
void
)
fflush
(
stderr
);
...
...
client/mysqltest.c
View file @
178f8e91
...
...
@@ -93,6 +93,12 @@ static uint global_expected_errno[MAX_EXPECTED_ERRORS];
DYNAMIC_ARRAY
q_lines
;
typedef
struct
{
char
file
[
FN_REFLEN
];
ulong
pos
;
}
MASTER_POS
;
struct
connection
{
MYSQL
mysql
;
...
...
@@ -106,6 +112,7 @@ typedef
}
PARSER
;
PARSER
parser
;
MASTER_POS
master_pos
;
int
block_ok
=
1
;
/* set to 0 if the current block should not be executed */
int
false_block_depth
=
0
;
const
char
*
result_file
=
0
;
/* if set, all results are concated and
...
...
@@ -139,13 +146,15 @@ struct st_query
enum
{
Q_CONNECTION
=
1
,
Q_QUERY
,
Q_CONNECT
,
Q_SLEEP
,
Q_INC
,
Q_DEC
,
Q_SOURCE
,
Q_DISCONNECT
,
Q_LET
,
Q_ECHO
,
Q_WHILE
,
Q_END_BLOCK
,
Q_SYSTEM
,
Q_RESULT
,
Q_REQUIRE
,
Q_ERROR
,
Q_SYSTEM
,
Q_RESULT
,
Q_REQUIRE
,
Q_SAVE_MASTER_POS
,
Q_SYNC_WITH_MASTER
,
Q_UNKNOWN
,
Q_COMMENT
,
Q_COMMENT_WITH_COMMAND
}
type
;
};
const
char
*
command_names
[]
=
{
"connection"
,
"query"
,
"connect"
,
"sleep"
,
"inc"
,
"dec"
,
"source"
,
"disconnect"
,
"let"
,
"echo"
,
"while"
,
"end"
,
"system"
,
"result"
,
"require"
,
"error"
,
0
"let"
,
"echo"
,
"while"
,
"end"
,
"system"
,
"result"
,
"require"
,
"save_master_pos"
,
"sync_with_master"
,
0
};
TYPELIB
command_typelib
=
{
array_elements
(
command_names
),
""
,
...
...
@@ -473,6 +482,50 @@ int do_echo(struct st_query* q)
return
0
;
}
int
do_sync_with_master
()
{
MYSQL_RES
*
res
;
MYSQL_ROW
row
;
MYSQL
*
mysql
=
&
cur_con
->
mysql
;
char
query_buf
[
FN_REFLEN
+
128
];
sprintf
(
query_buf
,
"select master_pos_wait('%s', %ld)"
,
master_pos
.
file
,
master_pos
.
pos
);
if
(
mysql_query
(
mysql
,
query_buf
))
die
(
"At line %u: failed in %s: %d: %s"
,
start_lineno
,
query_buf
,
mysql_errno
(
mysql
),
mysql_error
(
mysql
));
if
(
!
(
res
=
mysql_store_result
(
mysql
)))
die
(
"line %u: mysql_store_result() retuned NULL"
,
start_lineno
);
if
(
!
(
row
=
mysql_fetch_row
(
res
)))
die
(
"line %u: empty result in %s"
,
start_lineno
,
query_buf
);
if
(
!
row
[
0
])
die
(
"Error on slave while syncing with master"
);
mysql_free_result
(
res
);
return
0
;
}
int
do_save_master_pos
()
{
MYSQL_RES
*
res
;
MYSQL_ROW
row
;
MYSQL
*
mysql
=
&
cur_con
->
mysql
;
if
(
mysql_query
(
mysql
,
"show master status"
))
die
(
"At line %u: failed in show master status: %d: %s"
,
start_lineno
,
mysql_errno
(
mysql
),
mysql_error
(
mysql
));
if
(
!
(
res
=
mysql_store_result
(
mysql
)))
die
(
"line %u: mysql_store_result() retuned NULL"
,
start_lineno
);
if
(
!
(
row
=
mysql_fetch_row
(
res
)))
die
(
"line %u: empty result in show master status"
,
start_lineno
);
strncpy
(
master_pos
.
file
,
row
[
0
],
sizeof
(
master_pos
.
file
));
master_pos
.
pos
=
strtoul
(
row
[
1
],
(
char
**
)
0
,
10
);
mysql_free_result
(
res
);
return
0
;
}
int
do_let
(
struct
st_query
*
q
)
{
char
*
p
=
q
->
first_argument
;
...
...
@@ -1326,6 +1379,7 @@ int main(int argc, char** argv)
cur_con
=
cons
;
memset
(
file_stack
,
0
,
sizeof
(
file_stack
));
memset
(
&
master_pos
,
0
,
sizeof
(
master_pos
));
file_stack_end
=
file_stack
+
MAX_INCLUDE_DEPTH
;
cur_file
=
file_stack
;
lineno
=
lineno_stack
;
...
...
@@ -1391,6 +1445,8 @@ int main(int argc, char** argv)
get_file_name
(
save_file
,
q
);
require_file
=
1
;
break
;
case
Q_SAVE_MASTER_POS
:
do_save_master_pos
(
q
);
break
;
case
Q_SYNC_WITH_MASTER
:
do_sync_with_master
(
q
);
break
;
case
Q_COMMENT
:
/* Ignore row */
case
Q_COMMENT_WITH_COMMAND
:
default:
processed
=
0
;
break
;
...
...
mysql-test/mysql-test-run.sh
View file @
178f8e91
...
...
@@ -194,11 +194,13 @@ if [ x$SOURCE_DIST = x1 ] ; then
MYSQLD
=
"
$BASEDIR
/sql/mysqld"
MYSQL_TEST
=
"
$BASEDIR
/client/mysqltest"
MYSQLADMIN
=
"
$BASEDIR
/client/mysqladmin"
MYSQL
=
"
$BASEDIR
/client/mysql"
INSTALL_DB
=
"./install_test_db"
else
MYSQLD
=
"
$BASEDIR
/bin/mysqld"
MYSQL_TEST
=
"
$BASEDIR
/bin/mysqltest"
MYSQLADMIN
=
"
$BASEDIR
/bin/mysqladmin"
MYSQL
=
"
$BASEDIR
/bin/mysql"
INSTALL_DB
=
"./install_test_db -bin"
fi
...
...
@@ -235,6 +237,11 @@ SLAVE_MYSQLD=$MYSQLD #this can be changed later if we are doing gcov
#++
# Function Definitions
#--
wait_for_server_start
()
{
$MYSQL
-e
"select 1"
--silent
-w1
--host
=
127.0.0.1
--port
=
$1
\
>
/dev/null
}
prompt_user
()
{
...
...
@@ -325,6 +332,7 @@ gcov_collect () {
$ECHO
"gcov info in
$GCOV_MSG
, errors in
$GCOV_ERR
"
}
start_master
()
{
[
x
$MASTER_RUNNING
=
1
]
&&
return
...
...
@@ -359,6 +367,7 @@ start_master()
else
$MYSQLD
$master_args
>>
$MASTER_MYERR
2>&1 &
fi
wait_for_server_start
$MASTER_MYPORT
MASTER_RUNNING
=
1
}
...
...
@@ -404,6 +413,7 @@ start_slave()
else
$SLAVE_MYSQLD
$slave_args
>>
$SLAVE_MYERR
2>&1 &
fi
wait_for_server_start
$SLAVE_MYPORT
SLAVE_RUNNING
=
1
}
...
...
@@ -412,7 +422,6 @@ mysql_start () {
start_master
start_slave
cd
$MYSQL_TEST_DIR
sleep
$SLEEP_TIME
# Give mysqld time to start properly
return
1
}
...
...
@@ -435,7 +444,6 @@ stop_slave ()
fi
fi
SLAVE_RUNNING
=
0
sleep
$SLEEP_TIME
# Give mysqld time to go down properly
fi
}
...
...
@@ -458,7 +466,6 @@ stop_master ()
fi
fi
MASTER_RUNNING
=
0
sleep
$SLEEP_TIME
# Give mysqld time to go down properly
fi
}
...
...
@@ -468,7 +475,10 @@ mysql_stop ()
$ECHO
"Shutting-down MySQL daemon"
$ECHO
""
stop_master
$ECHO
"Master shutdown finished"
stop_slave
$ECHO
"Slave shutdown finished"
return
1
}
...
...
mysql-test/r/rpl000001.result
0 → 100644
View file @
178f8e91
n
1
2
sum(length(word))
71
mysql-test/r/rpl000014.result
View file @
178f8e91
File Position Binlog_do_db Binlog_ignore_db
master-bin.001 73
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db
127.0.0.1 root 9306 1 73 Yes
127.0.0.1 root 9306 1
master-bin.001
73 Yes
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db
127.0.0.1 root 9306 1 73 No
127.0.0.1 root 9306 1
master-bin.001
73 No
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db
127.0.0.1 root 9306 1 73 Yes
127.0.0.1 root 9306 1
master-bin.001
73 Yes
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db
127.0.0.1 root 9306 1 173 Yes
127.0.0.1 root 9306 1
master-bin.001
173 Yes
File Position Binlog_do_db Binlog_ignore_db
master-bin.001 73
n
...
...
mysql-test/t/rpl000001.test
View file @
178f8e91
...
...
@@ -7,12 +7,15 @@ load data infile '../../std_data/words.dat' into table t1;
drop
table
if
exists
foo
;
create
table
foo
(
n
int
);
insert
into
foo
values
(
1
),(
2
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
use
test
;
@
r
/
rpl000001
.
a
.
result
select
*
from
foo
;
@
r
/
rpl000001
.
b
.
result
select
sum
(
length
(
word
))
from
t1
;
select
*
from
foo
;
select
sum
(
length
(
word
))
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000002.test
View file @
178f8e91
...
...
@@ -5,8 +5,13 @@ drop table if exists t1;
create
table
t1
(
n
int
auto_increment
primary
key
);
set
insert_id
=
2000
;
insert
into
t1
values
(
NULL
),(
NULL
),(
NULL
);
save_master_pos
;
connection
slave
;
use
test
;
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000002
.
result
select
*
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000003.test
View file @
178f8e91
...
...
@@ -4,7 +4,12 @@ drop table if exists t1;
create
table
t1
(
n
int
primary
key
);
!
insert
into
t1
values
(
1
),(
2
),(
2
);
insert
into
t1
values
(
3
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000003
.
result
select
*
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000004.test
View file @
178f8e91
...
...
@@ -16,4 +16,11 @@ drop table if exists t2;
load
table
t2
from
master
;
@
r
/
rpl000004
.
a
.
result
check
table
t1
;
@
r
/
rpl000004
.
b
.
result
select
count
(
*
)
from
t2
;
connection
master
;
set
SQL_LOG_BIN
=
1
;
drop
table
if
exists
t1
,
t2
;
save_master_pos
;
connection
slave
;
sync_with_master
;
create
table
t1
(
n
int
);
drop
table
t1
;
mysql-test/t/rpl000005.test
View file @
178f8e91
...
...
@@ -7,8 +7,12 @@ INSERT t1 SET name='Jacob', age=2;
INSERT
into
t1
SET
name
=
'Caleb'
,
age
=
1
;
ALTER
TABLE
t1
ADD
id
int
(
8
)
ZEROFILL
AUTO_INCREMENT
PRIMARY
KEY
;
@
r
/
rpl000005
.
result
select
*
from
t1
;
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000005
.
result
select
*
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000006.test
View file @
178f8e91
...
...
@@ -12,3 +12,6 @@ load table foo from master;
@
r
/
rpl000006
.
result
select
unix_timestamp
(
t
)
from
foo
;
connection
master
;
drop
table
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000007.test
View file @
178f8e91
...
...
@@ -15,8 +15,12 @@ insert into foo values('five');
drop
table
if
exists
bar
;
create
table
bar
(
m
int
);
insert
into
bar
values
(
15
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000007
.
result
select
foo
.
n
,
bar
.
m
from
foo
,
bar
;
connection
master
;
drop
table
if
exists
bar
,
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000008.test
View file @
178f8e91
...
...
@@ -17,8 +17,13 @@ insert into bar values(15);
drop
table
if
exists
choo
;
create
table
choo
(
k
int
);
insert
into
choo
values
(
55
);
save_master_pos
;
connection
slave
;
s
leep
3
;
s
ync_with_master
;
@
r
/
rpl000008
.
result
select
foo
.
n
,
bar
.
m
,
choo
.
k
from
foo
,
bar
,
choo
;
connection
master
;
drop
table
if
exists
foo
,
bar
,
choo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
drop
table
if
exists
foo
,
bar
,
choo
;
mysql-test/t/rpl000009.test
View file @
178f8e91
...
...
@@ -6,8 +6,9 @@ drop database if exists foo;
create
database
foo
;
drop
database
if
exists
bar
;
create
database
bar
;
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
drop
table
if
exists
foo
.
foo
;
create
table
foo
.
foo
(
n
int
);
insert
into
foo
.
foo
values
(
4
);
...
...
@@ -18,9 +19,15 @@ insert into foo.foo values(5);
drop
table
if
exists
bar
.
bar
;
create
table
bar
.
bar
(
m
int
);
insert
into
bar
.
bar
values
(
15
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000009
.
result
select
foo
.
foo
.
n
,
bar
.
bar
.
m
from
foo
.
foo
,
bar
.
bar
;
connection
master
;
drop
database
if
exists
bar
;
drop
database
if
exists
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
drop
database
if
exists
bar
;
drop
database
if
exists
foo
;
mysql-test/t/rpl000010.test
View file @
178f8e91
...
...
@@ -8,8 +8,12 @@ drop table if exists t1;
create
table
t1
(
n
int
not
null
auto_increment
primary
key
);
insert
into
t1
values
(
NULL
);
insert
into
t1
values
(
2
);
save_master_pos
;
connection
slave
;
s
leep
5
;
s
ync_with_master
;
@
r
/
rpl000010
.
result
select
n
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000011.test
View file @
178f8e91
...
...
@@ -4,16 +4,21 @@ use test;
drop
table
if
exists
t1
;
create
table
t1
(
n
int
);
insert
into
t1
values
(
1
);
save_master_pos
;
connection
slave
;
#give slave some breathing room to get started
s
leep
2
;
s
ync_with_master
;
slave
stop
;
slave
start
;
connection
master
;
insert
into
t1
values
(
2
);
save_master_pos
;
connection
slave
;
#let slave catch up
s
leep
2
;
s
ync_with_master
;
@
r
/
rpl000011
.
result
select
*
from
t1
;
connection
master
;
drop
table
t1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000012.test
View file @
178f8e91
...
...
@@ -14,13 +14,18 @@ disconnect master;
connection
master1
;
insert
into
t2
values
(
6
);
disconnect
master1
;
connect
(
master2
,
localhost
,
root
,,
test
,
0
,
mysql
-
master
.
sock
);
connection
master2
;
save_master_pos
;
connection
slave
;
s
leep
1
;
s
ync_with_master
;
@
r
/
rpl000012
.
result
select
*
from
t2
;
@
r
/
rpl000012
.
status
.
result
show
status
like
'Slave_open_temp_tables'
;
#
# Clean up
#
connect
(
master2
,
localhost
,
root
,,
test
,
0
,
mysql
-
master
.
sock
);
connection
master2
;
drop
table
if
exists
t1
,
t2
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000013.test
View file @
178f8e91
source
include
/
master
-
slave
.
inc
;
connection
master
;
save_master_pos
;
connection
slave
;
sync_with_master
;
connection
master
;
drop
table
if
exists
t2
;
create
table
t2
(
n
int
);
create
temporary
table
t1
(
n
int
);
...
...
@@ -12,21 +16,19 @@ insert into t2 select * from t1;
disconnect
master
;
connection
master1
;
insert
into
t2
values
(
6
);
sleep
2
;
disconnect
master1
;
connect
(
master2
,
localhost
,
root
,,
test
,
0
,
mysql
-
master
.
sock
);
connection
master2
;
save_master_pos
;
connection
slave
;
let
$
1
=
12
;
while
(
$
1
)
{
!
slave
start
;
sleep
0.2
;
dec
$
1
;
}
sync_with_master
;
@
r
/
rpl000013
.
result
select
*
from
t2
;
@
r
/
rpl000013
.
status
.
result
show
status
like
'Slave_open_temp_tables'
;
#
# Clean up
#
connect
(
master2
,
localhost
,
root
,,
test
,
0
,
mysql
-
master
.
sock
);
connection
master2
;
drop
table
if
exists
t1
,
t2
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000014.test
View file @
178f8e91
...
...
@@ -2,11 +2,11 @@ source include/master-slave.inc;
source
include
/
have_default_master
.
inc
;
connection
master
;
show
master
status
;
save_master_pos
;
connection
slave
;
s
leep
0.2
;
s
ync_with_master
;
show
slave
status
;
change
master
to
master_log_pos
=
73
;
sleep
0.2
;
slave
stop
;
change
master
to
master_log_pos
=
73
;
show
slave
status
;
...
...
@@ -20,9 +20,13 @@ create table if not exists foo(n int);
drop
table
if
exists
foo
;
create
table
foo
(
n
int
);
insert
into
foo
values
(
1
),(
2
),(
3
);
save_master_pos
;
connection
slave
;
change
master
to
master_log_pos
=
73
;
s
leep
2
;
s
ync_with_master
;
select
*
from
foo
;
connection
master
;
drop
table
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000015.test
View file @
178f8e91
...
...
@@ -18,8 +18,13 @@ connection master;
drop
table
if
exists
foo
;
create
table
foo
(
n
int
);
insert
into
foo
values
(
10
),(
45
),(
90
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
select
*
from
foo
;
connection
master
;
drop
table
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
mysql-test/t/rpl000016.test
View file @
178f8e91
...
...
@@ -15,8 +15,9 @@ connection master;
drop
table
if
exists
t1
;
create
table
t1
(
s
text
);
insert
into
t1
values
(
'Could not break slave'
),(
'Tried hard'
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
select
*
from
t1
;
connection
master
;
flush
logs
;
...
...
@@ -24,12 +25,14 @@ drop table if exists t2;
create
table
t2
(
m
int
);
insert
into
t2
values
(
34
),(
67
),(
123
);
flush
logs
;
sleep
0.3
;
show
master
logs
;
purge
master
logs
to
'master-bin.003'
;
show
master
logs
;
insert
into
t2
values
(
65
);
save_master_pos
;
connection
slave
;
s
leep
2
;
s
ync_with_master
;
select
*
from
t2
;
drop
table
if
exists
t1
,
t2
;
connection
master
;
drop
table
if
exists
t1
,
t2
;
sql/item_create.cc
View file @
178f8e91
...
...
@@ -376,3 +376,8 @@ Item *create_load_file(Item* a)
{
return
new
Item_load_file
(
a
);
}
Item
*
create_wait_for_master_pos
(
Item
*
a
,
Item
*
b
)
{
return
new
Item_master_pos_wait
(
a
,
b
);
}
sql/item_create.h
View file @
178f8e91
...
...
@@ -85,3 +85,4 @@ Item *create_func_ucase(Item* a);
Item
*
create_func_version
(
void
);
Item
*
create_func_weekday
(
Item
*
a
);
Item
*
create_load_file
(
Item
*
a
);
Item
*
create_wait_for_master_pos
(
Item
*
a
,
Item
*
b
);
sql/item_func.cc
View file @
178f8e91
...
...
@@ -26,6 +26,7 @@
#include <hash.h>
#include <time.h>
#include <ft_global.h>
#include "slave.h" // for wait_for_master_pos
/* return TRUE if item is a constant */
...
...
@@ -1387,6 +1388,28 @@ void item_user_lock_release(ULL *ull)
delete
ull
;
}
/*
Wait until we are at or past the given position in the master binlog
on the slave
*/
longlong
Item_master_pos_wait
::
val_int
()
{
THD
*
thd
=
current_thd
;
String
*
log_name
=
args
[
0
]
->
val_str
(
&
value
);
int
event_count
;
if
(
thd
->
slave_thread
||
!
log_name
||
!
log_name
->
length
())
{
null_value
=
1
;
return
0
;
}
ulong
pos
=
(
ulong
)
args
[
1
]
->
val_int
();
if
((
event_count
=
glob_mi
.
wait_for_pos
(
thd
,
log_name
,
pos
))
==
-
1
)
null_value
=
1
;;
return
event_count
;
}
/*
Get a user level lock. If the thread has an old lock this is first released.
Returns 1: Got lock
...
...
sql/item_func.h
View file @
178f8e91
...
...
@@ -778,6 +778,18 @@ class Item_func_release_lock :public Item_int_func
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
1
;
maybe_null
=
1
;}
};
/* replication functions */
class
Item_master_pos_wait
:
public
Item_int_func
{
String
value
;
public:
Item_master_pos_wait
(
Item
*
a
,
Item
*
b
)
:
Item_int_func
(
a
,
b
)
{}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"master_pos_wait"
;
}
void
fix_length_and_dec
()
{
decimals
=
0
;
max_length
=
1
;
maybe_null
=
1
;}
};
/* Handling of user definiable variables */
...
...
sql/lex.h
View file @
178f8e91
...
...
@@ -398,6 +398,8 @@ static SYMBOL sql_functions[] = {
{
"LOWER"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_lcase
)},
{
"LPAD"
,
SYM
(
FUNC_ARG3
),
0
,
CREATE_FUNC
(
create_func_lpad
)},
{
"LTRIM"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_ltrim
)},
{
"MASTER_POS_WAIT"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_wait_for_master_pos
)},
{
"MAKE_SET"
,
SYM
(
MAKE_SET_SYM
),
0
,
0
},
{
"MAX"
,
SYM
(
MAX_SYM
),
0
,
0
},
{
"MD5"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_md5
)},
...
...
sql/slave.cc
View file @
178f8e91
...
...
@@ -616,6 +616,46 @@ int flush_master_info(MASTER_INFO* mi)
return
0
;
}
int
st_master_info
::
wait_for_pos
(
THD
*
thd
,
String
*
log_name
,
ulong
log_pos
)
{
if
(
!
inited
)
return
-
1
;
bool
pos_reached
=
0
;
int
event_count
=
0
;
for
(;
!
pos_reached
&&
!
thd
->
killed
;)
{
int
cmp_result
;
char
*
basename
;
pthread_mutex_lock
(
&
lock
);
if
(
*
log_file_name
)
{
basename
=
strrchr
(
log_file_name
,
FN_LIBCHAR
);
if
(
basename
)
++
basename
;
else
basename
=
log_file_name
;
cmp_result
=
strncmp
(
basename
,
log_name
->
ptr
(),
log_name
->
length
());
}
else
cmp_result
=
0
;
pos_reached
=
((
!
cmp_result
&&
pos
>=
log_pos
)
||
cmp_result
>
0
);
if
(
!
pos_reached
&&
!
thd
->
killed
)
{
const
char
*
msg
=
thd
->
enter_cond
(
&
cond
,
&
lock
,
"Waiting for master update"
);
pthread_cond_wait
(
&
cond
,
&
lock
);
thd
->
exit_cond
(
msg
);
event_count
++
;
}
pthread_mutex_unlock
(
&
lock
);
if
(
thd
->
killed
)
return
-
1
;
}
return
event_count
;
}
static
int
init_slave_thread
(
THD
*
thd
)
{
...
...
@@ -1003,10 +1043,17 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
{
Rotate_log_event
*
rev
=
(
Rotate_log_event
*
)
ev
;
int
ident_len
=
rev
->
ident_len
;
pthread_mutex_lock
(
&
mi
->
lock
);
memcpy
(
mi
->
log_file_name
,
rev
->
new_log_ident
,
ident_len
);
mi
->
log_file_name
[
ident_len
]
=
0
;
mi
->
pos
=
4
;
// skip magic number
pthread_cond_broadcast
(
&
mi
->
cond
);
pthread_mutex_unlock
(
&
mi
->
lock
);
flush_master_info
(
mi
);
#ifndef DBUG_OFF
if
(
abort_slave_event_count
)
++
events_till_abort
;
#endif
delete
ev
;
break
;
}
...
...
@@ -1045,6 +1092,9 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
pthread_handler_decl
(
handle_slave
,
arg
__attribute__
((
unused
)))
{
#ifndef DBUG_OFF
slave_begin:
#endif
THD
*
thd
;
// needs to be first for thread_stack
MYSQL
*
mysql
=
NULL
;
...
...
@@ -1068,8 +1118,8 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
#ifndef DBUG_OFF
events_till_abort
=
abort_slave_event_count
;
#endif
pthread_cond_broadcast
(
&
COND_slave_start
);
pthread_mutex_unlock
(
&
LOCK_slave
);
pthread_cond_broadcast
(
&
COND_slave_start
);
pthread_mutex_unlock
(
&
LOCK_slave
);
int
error
=
1
;
bool
retried_once
=
0
;
...
...
@@ -1241,6 +1291,10 @@ position %ld",
net_end
(
&
thd
->
net
);
// destructor will not free it, because we are weird
delete
thd
;
my_thread_end
();
#ifndef DBUG_OFF
if
(
abort_slave_event_count
&&
!
events_till_abort
)
goto
slave_begin
;
#endif
pthread_exit
(
0
);
DBUG_RETURN
(
0
);
// Can't return anything here
}
...
...
sql/slave.h
View file @
178f8e91
...
...
@@ -14,17 +14,20 @@ typedef struct st_master_info
uint
port
;
uint
connect_retry
;
pthread_mutex_t
lock
;
pthread_cond_t
cond
;
bool
inited
;
st_master_info
()
:
pending
(
0
),
fd
(
-
1
),
inited
(
0
)
{
host
[
0
]
=
0
;
user
[
0
]
=
0
;
password
[
0
]
=
0
;
pthread_mutex_init
(
&
lock
,
NULL
);
pthread_cond_init
(
&
cond
,
NULL
);
}
~
st_master_info
()
{
pthread_mutex_destroy
(
&
lock
);
pthread_cond_destroy
(
&
cond
);
}
inline
void
inc_pending
(
ulonglong
val
)
{
...
...
@@ -35,6 +38,7 @@ typedef struct st_master_info
pthread_mutex_lock
(
&
lock
);
pos
+=
val
+
pending
;
pending
=
0
;
pthread_cond_broadcast
(
&
cond
);
pthread_mutex_unlock
(
&
lock
);
}
// thread safe read of position - not needed if we are in the slave thread,
...
...
@@ -45,6 +49,8 @@ typedef struct st_master_info
var
=
pos
;
pthread_mutex_unlock
(
&
lock
);
}
int
wait_for_pos
(
THD
*
thd
,
String
*
log_name
,
ulong
log_pos
);
}
MASTER_INFO
;
typedef
struct
st_table_rule_ent
...
...
sql/sql_class.h
View file @
178f8e91
...
...
@@ -281,6 +281,25 @@ class THD :public ilink {
THD
();
~
THD
();
bool
store_globals
();
inline
const
char
*
enter_cond
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
const
char
*
msg
)
{
const
char
*
old_msg
=
proc_info
;
pthread_mutex_lock
(
&
mysys_var
->
mutex
);
mysys_var
->
current_mutex
=
mutex
;
mysys_var
->
current_cond
=
cond
;
proc_info
=
msg
;
pthread_mutex_unlock
(
&
mysys_var
->
mutex
);
return
old_msg
;
}
inline
void
exit_cond
(
const
char
*
old_msg
)
{
pthread_mutex_lock
(
&
mysys_var
->
mutex
);
mysys_var
->
current_mutex
=
0
;
mysys_var
->
current_cond
=
0
;
proc_info
=
old_msg
;
pthread_mutex_unlock
(
&
mysys_var
->
mutex
);
}
inline
time_t
query_start
()
{
query_start_used
=
1
;
return
start_time
;
}
inline
void
set_time
()
{
if
(
user_time
)
start_time
=
time_after_lock
=
user_time
;
else
time_after_lock
=
time
(
&
start_time
);
}
inline
void
end_time
()
{
time
(
&
start_time
);
}
...
...
sql/sql_repl.cc
View file @
178f8e91
...
...
@@ -26,6 +26,36 @@
extern
const
char
*
any_db
;
extern
pthread_handler_decl
(
handle_slave
,
arg
);
static
int
fake_rotate_event
(
NET
*
net
,
String
*
packet
,
const
char
*
log_file_name
);
static
int
fake_rotate_event
(
NET
*
net
,
String
*
packet
,
char
*
log_file_name
,
const
char
**
errmsg
)
{
char
header
[
LOG_EVENT_HEADER_LEN
];
memset
(
header
,
0
,
4
);
// when does not matter
header
[
EVENT_TYPE_OFFSET
]
=
ROTATE_EVENT
;
char
*
p
=
strrchr
(
log_file_name
,
FN_LIBCHAR
);
// find the last slash
if
(
p
)
p
++
;
else
p
=
log_file_name
;
uint
ident_len
=
(
uint
)
strlen
(
p
);
ulong
event_len
=
ident_len
+
sizeof
(
header
);
int4store
(
header
+
EVENT_TYPE_OFFSET
+
1
,
server_id
);
int4store
(
header
+
EVENT_LEN_OFFSET
,
event_len
);
packet
->
append
(
header
,
sizeof
(
header
));
packet
->
append
(
p
,
ident_len
);
if
(
my_net_write
(
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
()))
{
*
errmsg
=
"failed on my_net_write()"
;
return
-
1
;
}
return
0
;
}
static
int
send_file
(
THD
*
thd
)
{
...
...
@@ -281,6 +311,15 @@ sweepstakes if you report the bug";
// we need to start a packet with something other than 255
// to distiquish it from error
if
(
pos
==
4
)
// tell the client log name with a fake rotate_event
// if we are at the start of the log
{
if
(
fake_rotate_event
(
net
,
packet
,
log_file_name
,
&
errmsg
))
goto
err
;
packet
->
length
(
0
);
packet
->
append
(
"
\0
"
,
1
);
}
while
(
!
net
->
error
&&
net
->
vio
!=
0
&&
!
thd
->
killed
)
{
pthread_mutex_t
*
log_lock
=
mysql_bin_log
.
get_log_lock
();
...
...
@@ -437,36 +476,15 @@ sweepstakes if you report the bug";
end_io_cache
(
&
log
);
(
void
)
my_close
(
file
,
MYF
(
MY_WME
));
if
((
file
=
open_log
(
&
log
,
log_file_name
,
&
errmsg
))
<
0
)
goto
err
;
// fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset
{
char
header
[
LOG_EVENT_HEADER_LEN
];
memset
(
header
,
0
,
4
);
// when does not matter
header
[
EVENT_TYPE_OFFSET
]
=
ROTATE_EVENT
;
char
*
p
=
strrchr
(
log_file_name
,
FN_LIBCHAR
);
// find the last slash
if
(
p
)
p
++
;
else
p
=
log_file_name
;
uint
ident_len
=
(
uint
)
strlen
(
p
);
ulong
event_len
=
ident_len
+
sizeof
(
header
);
int4store
(
header
+
EVENT_TYPE_OFFSET
+
1
,
server_id
);
int4store
(
header
+
EVENT_LEN_OFFSET
,
event_len
);
packet
->
append
(
header
,
sizeof
(
header
));
packet
->
append
(
p
,
ident_len
);
if
(
my_net_write
(
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
()))
{
errmsg
=
"failed on my_net_write()"
;
goto
err
;
}
packet
->
length
(
0
);
packet
->
append
(
"
\0
"
,
1
);
}
if
((
file
=
open_log
(
&
log
,
log_file_name
,
&
errmsg
))
<
0
||
fake_rotate_event
(
net
,
packet
,
log_file_name
,
&
errmsg
))
goto
err
;
packet
->
length
(
0
);
packet
->
append
(
"
\0
"
,
1
);
}
}
...
...
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