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
73e6a690
Commit
73e6a690
authored
May 28, 2001
by
sasha@mysql.sashanet.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge work:/home/bk/mysql-4.0
into mysql.sashanet.com:/home/sasha/src/bk/mysql-4.0
parents
6eddbc48
8f6b34f9
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
932 additions
and
83 deletions
+932
-83
include/mysqld_error.h
include/mysqld_error.h
+3
-1
mysql-test/r/rpl000009.result
mysql-test/r/rpl000009.result
+30
-0
mysql-test/t/rpl000009.test
mysql-test/t/rpl000009.test
+53
-0
sql/mini_client.cc
sql/mini_client.cc
+508
-0
sql/mini_client.h
sql/mini_client.h
+11
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-2
sql/share/english/errmsg.txt
sql/share/english/errmsg.txt
+7
-2
sql/slave.cc
sql/slave.cc
+23
-15
sql/slave.h
sql/slave.h
+8
-3
sql/sql_base.cc
sql/sql_base.cc
+0
-19
sql/sql_class.cc
sql/sql_class.cc
+0
-1
sql/sql_class.h
sql/sql_class.h
+0
-2
sql/sql_db.cc
sql/sql_db.cc
+55
-34
sql/sql_lex.h
sql/sql_lex.h
+1
-1
sql/sql_parse.cc
sql/sql_parse.cc
+8
-3
sql/sql_repl.cc
sql/sql_repl.cc
+216
-0
sql/sql_repl.h
sql/sql_repl.h
+2
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+5
-0
No files found.
include/mysqld_error.h
View file @
73e6a690
...
...
@@ -205,4 +205,6 @@
#define ER_SLAVE_THREAD 1202
#define ER_TOO_MANY_USER_CONNECTIONS 1203
#define ER_SET_CONSTANTS_ONLY 1204
#define ER_ERROR_MESSAGES 205
#define ER_CONNECT_TO_MASTER 1205
#define ER_QUERY_ON_MASTER 1206
#define ER_ERROR_MESSAGES 207
mysql-test/r/rpl000009.result
View file @
73e6a690
n m
4 15
Database
bar
foo
mysql
test
Database
mysql
test
Database
bar
foo
mysql
test
Tables_in_foo
Tables_in_bar
t1
t2
n s
1 one bar
2 two bar
3 three bar
n s
11 eleven bar
12 twelve bar
13 thirteen bar
n s
1 one bar
2 two bar
3 three bar
4 four bar
mysql-test/t/rpl000009.test
View file @
73e6a690
...
...
@@ -31,3 +31,56 @@ connection slave;
sync_with_master
;
drop
database
if
exists
bar
;
drop
database
if
exists
foo
;
#now let's test load data from master
#first create some databases and tables on the master
connection
master
;
set
sql_log_bin
=
0
;
create
database
foo
;
create
database
bar
;
show
databases
;
create
table
foo
.
t1
(
n
int
,
s
char
(
20
));
create
table
foo
.
t2
(
n
int
,
s
text
);
insert
into
foo
.
t1
values
(
1
,
'one'
),
(
2
,
'two'
),
(
3
,
'three'
);
insert
into
foo
.
t2
values
(
11
,
'eleven'
),
(
12
,
'twelve'
),
(
13
,
'thirteen'
);
create
table
bar
.
t1
(
n
int
,
s
char
(
20
));
create
table
bar
.
t2
(
n
int
,
s
text
);
insert
into
bar
.
t1
values
(
1
,
'one bar'
),
(
2
,
'two bar'
),
(
3
,
'three bar'
);
insert
into
bar
.
t2
values
(
11
,
'eleven bar'
),
(
12
,
'twelve bar'
),
(
13
,
'thirteen bar'
);
set
sql_log_bin
=
1
;
save_master_pos
;
connection
slave
;
sync_with_master
;
#this should show that the slave is empty at this point
show
databases
;
load
data
from
master
;
#now let's check if we have the right tables and the right data in them
show
databases
;
use
foo
;
show
tables
;
use
bar
;
show
tables
;
select
*
from
bar
.
t1
;
select
*
from
bar
.
t2
;
#now let's see if replication works
connection
master
;
insert
into
bar
.
t1
values
(
4
,
'four bar'
);
save_master_pos
;
connection
slave
;
sync_with_master
;
select
*
from
bar
.
t1
;
#now time for cleanup
connection
master
;
drop
database
bar
;
drop
database
foo
;
save_master_pos
;
connection
slave
;
sync_with_master
;
sql/mini_client.cc
View file @
73e6a690
This diff is collapsed.
Click to expand it.
sql/mini_client.h
View file @
73e6a690
...
...
@@ -42,6 +42,17 @@ char * STDCALL mc_mysql_error(MYSQL *mysql);
int
STDCALL
mc_mysql_errno
(
MYSQL
*
mysql
);
my_bool
STDCALL
mc_mysql_reconnect
(
MYSQL
*
mysql
);
int
STDCALL
mc_mysql_send_query
(
MYSQL
*
mysql
,
const
char
*
query
,
uint
length
);
int
STDCALL
mc_mysql_read_query_result
(
MYSQL
*
mysql
);
int
STDCALL
mc_mysql_query
(
MYSQL
*
mysql
,
const
char
*
query
,
uint
length
);
MYSQL_RES
*
STDCALL
mc_mysql_store_result
(
MYSQL
*
mysql
);
void
STDCALL
mc_mysql_free_result
(
MYSQL_RES
*
result
);
void
STDCALL
mc_mysql_data_seek
(
MYSQL_RES
*
result
,
my_ulonglong
row
);
my_ulonglong
STDCALL
mc_mysql_num_rows
(
MYSQL_RES
*
res
);
unsigned
int
STDCALL
mc_mysql_num_fields
(
MYSQL_RES
*
res
);
MYSQL_ROW
STDCALL
mc_mysql_fetch_row
(
MYSQL_RES
*
res
);
int
STDCALL
mc_mysql_select_db
(
MYSQL
*
mysql
,
const
char
*
db
);
#endif
sql/mysql_priv.h
View file @
73e6a690
...
...
@@ -223,7 +223,7 @@ inline THD *_current_thd(void)
#include "opt_range.h"
void
mysql_create_db
(
THD
*
thd
,
char
*
db
,
uint
create_info
);
int
mysql_create_db
(
THD
*
thd
,
char
*
db
,
uint
create_info
);
void
mysql_binlog_send
(
THD
*
thd
,
char
*
log_ident
,
ulong
pos
,
ushort
flags
);
int
mysql_rm_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
my_bool
if_exists
);
int
quick_rm_table
(
enum
db_type
base
,
const
char
*
db
,
...
...
@@ -245,7 +245,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char
*
packet
,
uint
packet_length
);
bool
check_stack_overrun
(
THD
*
thd
,
char
*
dummy
);
bool
reload_acl_and_cache
(
THD
*
thd
,
uint
options
,
TABLE_LIST
*
tables
);
void
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
);
int
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
);
void
table_cache_init
(
void
);
void
table_cache_free
(
void
);
uint
cached_tables
(
void
);
...
...
sql/share/english/errmsg.txt
View file @
73e6a690
...
...
@@ -153,7 +153,7 @@
"You have an error in your SQL syntax",
"Delayed insert thread couldn't get requested lock for table %-.64s",
"Too many delayed threads in use",
"Aborted connection %ld to db: '%-.64s' user: '%-.32s' (%-.64s)",
"Aborted connection %ld to db: '%-.64s' user: '%-.32s' (%-.64s)
- see http://www.mysql.com/doc/C/o/Communication_errors.html
",
"Got a packet bigger than 'max_allowed_packet'",
"Got a read error from the connection pipe",
"Got an error from fcntl()",
...
...
@@ -185,7 +185,7 @@
"Got error %d during ROLLBACK",
"Got error %d during FLUSH_LOGS",
"Got error %d during CHECKPOINT",
"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)",
"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)
- see http://www.mysql.com/doc/C/o/Communication_errors.html
",
"The handler for the table does not support binary table dump",
"Binlog closed, cannot RESET MASTER",
"Failed rebuilding the index of dumped table '%-.64s'",
...
...
@@ -206,3 +206,8 @@
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
sql/slave.cc
View file @
73e6a690
...
...
@@ -20,6 +20,7 @@
#include <myisam.h>
#include "mini_client.h"
#include "slave.h"
#include "sql_repl.h"
#include <thr_alarm.h>
#include <my_dir.h>
...
...
@@ -55,7 +56,7 @@ static int init_slave_thread(THD* thd);
static
int
safe_connect
(
THD
*
thd
,
MYSQL
*
mysql
,
MASTER_INFO
*
mi
);
static
int
safe_reconnect
(
THD
*
thd
,
MYSQL
*
mysql
,
MASTER_INFO
*
mi
);
static
int
safe_sleep
(
THD
*
thd
,
int
sec
);
static
int
request_table_dump
(
MYSQL
*
mysql
,
c
har
*
db
,
char
*
table
);
static
int
request_table_dump
(
MYSQL
*
mysql
,
c
onst
char
*
db
,
const
char
*
table
);
static
int
create_table_from_dump
(
THD
*
thd
,
NET
*
net
,
const
char
*
db
,
const
char
*
table_name
);
inline
char
*
rewrite_db
(
char
*
db
);
...
...
@@ -344,7 +345,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
thd
->
proc_info
=
"Creating table from master dump"
;
// save old db in case we are creating in a different database
char
*
save_db
=
thd
->
db
;
thd
->
db
=
thd
->
last_nx_
db
;
thd
->
db
=
(
char
*
)
db
;
mysql_parse
(
thd
,
thd
->
query
,
packet_len
);
// run create table
thd
->
db
=
save_db
;
// leave things the way the were before
...
...
@@ -400,31 +401,39 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
return
error
;
}
int
fetch_nx_table
(
THD
*
thd
,
MASTER_INFO
*
mi
)
int
fetch_nx_table
(
THD
*
thd
,
const
char
*
db_name
,
const
char
*
table_name
,
MASTER_INFO
*
mi
,
MYSQL
*
mysql
)
{
MYSQL
*
mysql
=
mc_mysql_init
(
NULL
);
int
error
=
1
;
int
nx_errno
=
0
;
if
(
!
mysql
)
bool
called_connected
=
(
mysql
!=
NULL
);
if
(
!
called_connected
&&
!
(
mysql
=
mc_mysql_init
(
NULL
)))
{
sql_print_error
(
"fetch_nx_table: Error in mysql_init()"
);
nx_errno
=
ER_GET_ERRNO
;
goto
err
;
}
safe_connect
(
thd
,
mysql
,
mi
);
if
(
slave_killed
(
thd
))
goto
err
;
if
(
request_table_dump
(
mysql
,
thd
->
last_nx_db
,
thd
->
last_nx_table
))
if
(
!
called_connected
)
{
if
(
connect_to_master
(
thd
,
mysql
,
mi
))
{
sql_print_error
(
"Could not connect to master while fetching table\
'%-64s.%-64s'"
,
db_name
,
table_name
);
nx_errno
=
ER_CONNECT_TO_MASTER
;
goto
err
;
}
}
if
(
request_table_dump
(
mysql
,
db_name
,
table_name
))
{
nx_errno
=
ER_GET_ERRNO
;
sql_print_error
(
"fetch_nx_table: failed on table dump request "
);
goto
err
;
}
if
(
create_table_from_dump
(
thd
,
&
mysql
->
net
,
thd
->
last_nx_db
,
t
hd
->
last_nx_tabl
e
))
if
(
create_table_from_dump
(
thd
,
&
mysql
->
net
,
db_name
,
t
able_nam
e
))
{
// create_table_from_dump will have sent the error alread
sql_print_error
(
"fetch_nx_table: failed on create table "
);
...
...
@@ -434,7 +443,7 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi)
error
=
0
;
err:
if
(
mysql
)
if
(
mysql
&&
!
called_connected
)
mc_mysql_close
(
mysql
);
if
(
nx_errno
&&
thd
->
net
.
vio
)
send_error
(
&
thd
->
net
,
nx_errno
,
"Error in fetch_nx_table"
);
...
...
@@ -764,7 +773,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
return
0
;
}
static
int
request_table_dump
(
MYSQL
*
mysql
,
c
har
*
db
,
char
*
table
)
static
int
request_table_dump
(
MYSQL
*
mysql
,
c
onst
char
*
db
,
const
char
*
table
)
{
char
buf
[
1024
];
char
*
p
=
buf
;
...
...
@@ -901,7 +910,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
query_id
=
query_id
++
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
thd
->
last_nx_table
=
thd
->
last_nx_db
=
0
;
thd
->
query_error
=
0
;
// clear error
thd
->
net
.
last_errno
=
0
;
thd
->
net
.
last_error
[
0
]
=
0
;
...
...
sql/slave.h
View file @
73e6a690
#ifndef SLAVE_H
#define SLAVE_H
#include "mysql.h"
typedef
struct
st_master_info
{
char
log_file_name
[
FN_REFLEN
];
...
...
@@ -65,11 +67,14 @@ typedef struct st_table_rule_ent
int
flush_master_info
(
MASTER_INFO
*
mi
);
int
mysql_table_dump
(
THD
*
thd
,
char
*
db
,
char
*
tbl_name
,
int
fd
=
-
1
);
int
mysql_table_dump
(
THD
*
thd
,
const
char
*
db
,
const
char
*
tbl_name
,
int
fd
=
-
1
);
// if fd is -1, dump to NET
int
fetch_nx_table
(
THD
*
thd
,
MASTER_INFO
*
mi
);
int
fetch_nx_table
(
THD
*
thd
,
const
char
*
db_name
,
const
char
*
table_name
,
MASTER_INFO
*
mi
,
MYSQL
*
mysql
);
// retrieve non-exitent table from master
// the caller must set thd->last_nx_table and thd->last_nx_db first
int
show_master_info
(
THD
*
thd
);
int
show_binlog_info
(
THD
*
thd
);
...
...
sql/sql_base.cc
View file @
73e6a690
...
...
@@ -837,25 +837,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
!
(
table
->
table_cache_key
=
memdup_root
(
&
table
->
mem_root
,(
char
*
)
key
,
key_length
)))
{
MEM_ROOT
*
glob_alloc
;
LINT_INIT
(
glob_alloc
);
if
(
errno
==
ENOENT
&&
(
glob_alloc
=
my_pthread_getspecific_ptr
(
MEM_ROOT
*
,
THR_MALLOC
)))
// Sasha: needed for replication
// remember the name of the non-existent table
// so we can try to download it from the master
{
int
table_name_len
=
(
uint
)
strlen
(
table_name
);
int
db_len
=
(
uint
)
strlen
(
db
);
thd
->
last_nx_db
=
alloc_root
(
glob_alloc
,
db_len
+
table_name_len
+
2
);
if
(
thd
->
last_nx_db
)
{
thd
->
last_nx_table
=
thd
->
last_nx_db
+
db_len
+
1
;
memcpy
(
thd
->
last_nx_table
,
table_name
,
table_name_len
+
1
);
memcpy
(
thd
->
last_nx_db
,
db
,
db_len
+
1
);
}
}
table
->
next
=
table
->
prev
=
table
;
free_cache_entry
(
table
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
...
...
sql/sql_class.cc
View file @
73e6a690
...
...
@@ -96,7 +96,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
current_linfo
=
0
;
slave_thread
=
0
;
slave_proxy_id
=
0
;
last_nx_table
=
last_nx_db
=
0
;
cond_count
=
0
;
convert_set
=
0
;
mysys_var
=
0
;
...
...
sql/sql_class.h
View file @
73e6a690
...
...
@@ -242,8 +242,6 @@ class THD :public ilink {
enum
enum_server_command
command
;
uint32
server_id
;
const
char
*
where
;
char
*
last_nx_table
;
// last non-existent table, we need this for replication
char
*
last_nx_db
;
// database of the last nx table
time_t
start_time
,
time_after_lock
,
user_time
;
time_t
connect_time
,
thr_create_time
;
// track down slow pthread_create
thr_lock_type
update_lock_default
;
...
...
sql/sql_db.cc
View file @
73e6a690
...
...
@@ -30,11 +30,12 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
/* db-name is already validated when we come here */
void
mysql_create_db
(
THD
*
thd
,
char
*
db
,
uint
create_options
)
int
mysql_create_db
(
THD
*
thd
,
char
*
db
,
uint
create_options
)
{
char
path
[
FN_REFLEN
+
16
];
MY_DIR
*
dirp
;
long
result
=
1
;
int
error
=
0
;
DBUG_ENTER
(
"mysql_create_db"
);
VOID
(
pthread_mutex_lock
(
&
LOCK_mysql_create_db
));
...
...
@@ -47,7 +48,9 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
my_dirend
(
dirp
);
if
(
!
(
create_options
&
HA_LEX_CREATE_IF_NOT_EXISTS
))
{
net_printf
(
&
thd
->
net
,
ER_DB_CREATE_EXISTS
,
db
);
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_CREATE_EXISTS
,
db
);
error
=
1
;
goto
exit
;
}
result
=
0
;
...
...
@@ -57,34 +60,39 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
strend
(
path
)[
-
1
]
=
0
;
// Remove last '/' from path
if
(
my_mkdir
(
path
,
0777
,
MYF
(
0
))
<
0
)
{
net_printf
(
&
thd
->
net
,
ER_CANT_CREATE_DB
,
db
,
my_errno
);
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_CANT_CREATE_DB
,
db
,
my_errno
);
error
=
1
;
goto
exit
;
}
}
if
(
!
thd
->
query
)
{
thd
->
query
=
path
;
thd
->
query_length
=
(
uint
)
(
strxmov
(
path
,
"create database "
,
db
,
NullS
)
-
path
);
}
if
(
thd
)
{
mysql_update_log
.
write
(
thd
,
thd
->
query
,
thd
->
query_length
);
if
(
mysql_bin_log
.
is_open
())
if
(
!
thd
->
query
)
{
Query_log_event
qinfo
(
thd
,
thd
->
query
);
mysql_bin_log
.
write
(
&
qinfo
);
thd
->
query
=
path
;
thd
->
query_length
=
(
uint
)
(
strxmov
(
path
,
"create database "
,
db
,
NullS
)
-
path
);
}
{
mysql_update_log
.
write
(
thd
,
thd
->
query
,
thd
->
query_length
);
if
(
mysql_bin_log
.
is_open
())
{
Query_log_event
qinfo
(
thd
,
thd
->
query
);
mysql_bin_log
.
write
(
&
qinfo
);
}
}
if
(
thd
->
query
==
path
)
{
thd
->
query
=
0
;
// just in case
thd
->
query_length
=
0
;
}
send_ok
(
&
thd
->
net
,
result
);
}
if
(
thd
->
query
==
path
)
{
thd
->
query
=
0
;
// just in case
thd
->
query_length
=
0
;
}
send_ok
(
&
thd
->
net
,
result
);
exit:
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
error
)
;
}
const
char
*
del_exts
[]
=
...
...
@@ -94,10 +102,14 @@ static TYPELIB deletable_extentions=
/* db-name is already validated when we come here */
void
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
)
/* If thd == 0, do not write any messages
This is useful in replication when we want to remove
a stale database before replacing it with the new one
*/
int
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
)
{
long
deleted
=
0
;
int
error
=
0
;
char
path
[
FN_REFLEN
+
16
];
MY_DIR
*
dirp
;
DBUG_ENTER
(
"mysql_rm_db"
);
...
...
@@ -110,15 +122,19 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
/* See if the directory exists */
if
(
!
(
dirp
=
my_dir
(
path
,
MYF
(
MY_WME
|
MY_DONT_SORT
))))
{
if
(
!
if_exists
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_EXISTS
,
db
);
else
send_ok
(
&
thd
->
net
,
0
);
if
(
thd
)
{
if
(
!
if_exists
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_EXISTS
,
db
);
else
send_ok
(
&
thd
->
net
,
0
);
}
error
=
!
if_exists
;
goto
exit
;
}
remove_db_from_cache
(
db
);
if
((
deleted
=
mysql_rm_known_files
(
thd
,
dirp
,
path
,
0
))
>=
0
)
if
((
deleted
=
mysql_rm_known_files
(
thd
,
dirp
,
path
,
0
))
>=
0
&&
thd
)
{
if
(
!
thd
->
query
)
{
...
...
@@ -137,13 +153,14 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
thd
->
query
=
0
;
// just in case
thd
->
query_length
=
0
;
}
send_ok
(
&
thd
->
net
,(
ulong
)
deleted
);
}
exit:
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
error
)
;
}
/*
...
...
@@ -151,6 +168,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
are 2 digits (raid directories).
*/
/* This one also needs to work with thd == 0 for replication */
static
long
mysql_rm_known_files
(
THD
*
thd
,
MY_DIR
*
dirp
,
const
char
*
org_path
,
uint
level
)
{
...
...
@@ -162,7 +180,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
/* remove all files with known extensions */
for
(
uint
idx
=
2
;
idx
<
(
uint
)
dirp
->
number_off_files
&&
!
thd
->
killed
;
idx
<
(
uint
)
dirp
->
number_off_files
&&
(
!
thd
||
!
thd
->
killed
)
;
idx
++
)
{
FILEINFO
*
file
=
dirp
->
dir_entry
+
idx
;
...
...
@@ -196,7 +214,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
unpack_filename
(
filePath
,
filePath
);
if
(
my_delete
(
filePath
,
MYF
(
MY_WME
)))
{
net_printf
(
&
thd
->
net
,
ER_DB_DROP_DELETE
,
filePath
,
my_error
);
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_DELETE
,
filePath
,
my_error
);
my_dirend
(
dirp
);
DBUG_RETURN
(
-
1
);
}
...
...
@@ -205,7 +224,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
my_dirend
(
dirp
);
if
(
thd
->
killed
)
if
(
thd
&&
thd
->
killed
)
{
send_error
(
&
thd
->
net
,
ER_SERVER_SHUTDOWN
);
DBUG_RETURN
(
-
1
);
...
...
@@ -229,7 +248,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
/* Don't give errors if we can't delete 'RAID' directory */
if
(
level
)
DBUG_RETURN
(
deleted
);
send_error
(
&
thd
->
net
);
if
(
thd
)
send_error
(
&
thd
->
net
);
DBUG_RETURN
(
-
1
);
}
path
=
filePath
;
...
...
@@ -242,7 +262,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
/* Don't give errors if we can't delete 'RAID' directory */
if
(
rmdir
(
path
)
<
0
&&
!
level
)
{
net_printf
(
&
thd
->
net
,
ER_DB_DROP_RMDIR
,
path
,
errno
);
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_RMDIR
,
path
,
errno
);
DBUG_RETURN
(
-
1
);
}
}
...
...
sql/sql_lex.h
View file @
73e6a690
...
...
@@ -53,7 +53,7 @@ enum enum_sql_command {
SQLCOM_BEGIN
,
SQLCOM_LOAD_MASTER_TABLE
,
SQLCOM_CHANGE_MASTER
,
SQLCOM_RENAME_TABLE
,
SQLCOM_BACKUP_TABLE
,
SQLCOM_RESTORE_TABLE
,
SQLCOM_RESET
,
SQLCOM_PURGE
,
SQLCOM_SHOW_BINLOGS
,
SQLCOM_SHOW_OPEN_TABLES
,
SQLCOM_SHOW_OPEN_TABLES
,
SQLCOM_LOAD_MASTER_DATA
,
SQLCOM_HA_OPEN
,
SQLCOM_HA_CLOSE
,
SQLCOM_HA_READ
};
...
...
sql/sql_parse.cc
View file @
73e6a690
...
...
@@ -1203,6 +1203,13 @@ mysql_execute_command(void)
res
=
show_binlog_info
(
thd
);
break
;
}
case
SQLCOM_LOAD_MASTER_DATA
:
// sync with master
if
(
check_process_priv
(
thd
))
goto
error
;
res
=
load_master_data
(
thd
);
break
;
case
SQLCOM_LOAD_MASTER_TABLE
:
if
(
!
tables
->
db
)
...
...
@@ -1226,9 +1233,7 @@ mysql_execute_command(void)
break
;
}
thd
->
last_nx_table
=
tables
->
real_name
;
thd
->
last_nx_db
=
tables
->
db
;
if
(
fetch_nx_table
(
thd
,
&
glob_mi
))
if
(
fetch_nx_table
(
thd
,
tables
->
db
,
tables
->
real_name
,
&
glob_mi
,
0
))
// fetch_nx_table is responsible for sending
// the error
{
...
...
sql/sql_repl.cc
View file @
73e6a690
...
...
@@ -21,6 +21,7 @@
#include "sql_repl.h"
#include "sql_acl.h"
#include "log_event.h"
#include "mini_client.h"
#include <thr_alarm.h>
#include <my_dir.h>
...
...
@@ -845,5 +846,220 @@ int show_binlogs(THD* thd)
return
1
;
}
int
connect_to_master
(
THD
*
thd
,
MYSQL
*
mysql
,
MASTER_INFO
*
mi
)
{
if
(
!
mc_mysql_connect
(
mysql
,
mi
->
host
,
mi
->
user
,
mi
->
password
,
0
,
mi
->
port
,
0
,
0
))
{
sql_print_error
(
"Connection to master failed: %s"
,
mc_mysql_error
(
mysql
));
return
1
;
}
return
0
;
}
static
inline
void
cleanup_mysql_results
(
MYSQL_RES
*
db_res
,
MYSQL_RES
**
cur
,
MYSQL_RES
**
start
)
{
for
(
;
cur
>=
start
;
--
cur
)
if
(
*
cur
)
mc_mysql_free_result
(
*
cur
);
mc_mysql_free_result
(
db_res
);
}
static
inline
int
fetch_db_tables
(
THD
*
thd
,
MYSQL
*
mysql
,
const
char
*
db
,
MYSQL_RES
*
table_res
)
{
MYSQL_ROW
row
;
for
(
row
=
mc_mysql_fetch_row
(
table_res
);
row
;
row
=
mc_mysql_fetch_row
(
table_res
))
{
TABLE_LIST
table
;
const
char
*
table_name
=
row
[
0
];
int
error
;
if
(
table_rules_on
)
{
table
.
next
=
0
;
table
.
db
=
(
char
*
)
db
;
table
.
real_name
=
(
char
*
)
table_name
;
if
(
!
tables_ok
(
thd
,
&
table
))
continue
;
}
if
((
error
=
fetch_nx_table
(
thd
,
db
,
table_name
,
&
glob_mi
,
mysql
)))
return
error
;
}
return
0
;
}
int
load_master_data
(
THD
*
thd
)
{
MYSQL
mysql
;
MYSQL_RES
*
master_status_res
=
0
;
bool
slave_was_running
=
0
;
int
error
=
0
;
mc_mysql_init
(
&
mysql
);
pthread_mutex_lock
(
&
LOCK_slave
);
// we do not want anyone messing with the slave at all for the entire
// duration of the data load;
// first, kill the slave
if
((
slave_was_running
=
slave_running
))
{
abort_slave
=
1
;
thr_alarm_kill
(
slave_real_id
);
thd
->
proc_info
=
"waiting for slave to die"
;
while
(
slave_running
)
pthread_cond_wait
(
&
COND_slave_stopped
,
&
LOCK_slave
);
// wait until done
}
if
(
connect_to_master
(
thd
,
&
mysql
,
&
glob_mi
))
{
net_printf
(
&
thd
->
net
,
error
=
ER_CONNECT_TO_MASTER
,
mc_mysql_error
(
&
mysql
));
goto
err
;
}
// now that we are connected, get all database and tables in each
{
MYSQL_RES
*
db_res
,
**
table_res
,
**
table_res_end
,
**
cur_table_res
;
uint
num_dbs
;
MYSQL_ROW
row
;
if
(
mc_mysql_query
(
&
mysql
,
"show databases"
,
0
)
||
!
(
db_res
=
mc_mysql_store_result
(
&
mysql
)))
{
net_printf
(
&
thd
->
net
,
error
=
ER_QUERY_ON_MASTER
,
mc_mysql_error
(
&
mysql
));
goto
err
;
}
if
(
!
(
num_dbs
=
mc_mysql_num_rows
(
db_res
)))
goto
err
;
// in theory, the master could have no databases at all
// and run with skip-grant
if
(
!
(
table_res
=
(
MYSQL_RES
**
)
thd
->
alloc
(
num_dbs
*
sizeof
(
MYSQL_RES
*
))))
{
net_printf
(
&
thd
->
net
,
error
=
ER_OUTOFMEMORY
);
goto
err
;
}
// this is a temporary solution until we have online backup
// capabilities - to be replaced once online backup is working
// we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
// can to minimize the lock time
if
(
mc_mysql_query
(
&
mysql
,
"FLUSH TABLES WITH READ LOCK"
,
0
)
||
mc_mysql_query
(
&
mysql
,
"SHOW MASTER STATUS"
,
0
)
||
!
(
master_status_res
=
mc_mysql_store_result
(
&
mysql
)))
{
net_printf
(
&
thd
->
net
,
error
=
ER_QUERY_ON_MASTER
,
mc_mysql_error
(
&
mysql
));
goto
err
;
}
// go through every table in every database, and if the replication
// rules allow replicating it, get it
table_res_end
=
table_res
+
num_dbs
;
for
(
cur_table_res
=
table_res
;
cur_table_res
<
table_res_end
;
++
cur_table_res
)
{
MYSQL_ROW
row
=
mc_mysql_fetch_row
(
db_res
);
// since we know how many rows we have, this can never be NULL
char
*
db
=
row
[
0
];
int
drop_error
=
0
;
// do not replicate databases excluded by rules
// also skip mysql database - in most cases the user will
// mess up and not exclude mysql database with the rules when
// he actually means to - in this case, he is up for a surprise if
// his priv tables get dropped and downloaded from master
// TO DO - add special option, not enabled
// by default, to allow inclusion of mysql database into load
// data from master
if
(
!
db_ok
(
db
,
replicate_do_db
,
replicate_ignore_db
)
||
!
strcmp
(
db
,
"mysql"
))
{
*
cur_table_res
=
0
;
continue
;
}
if
((
drop_error
=
mysql_rm_db
(
0
,
db
,
1
))
||
mysql_create_db
(
0
,
db
,
0
))
{
error
=
(
drop_error
)
?
ER_DB_DROP_DELETE
:
ER_CANT_CREATE_DB
;
net_printf
(
&
thd
->
net
,
error
,
db
,
my_error
);
cleanup_mysql_results
(
db_res
,
cur_table_res
-
1
,
table_res
);
goto
err
;
}
if
(
mc_mysql_select_db
(
&
mysql
,
db
)
||
mc_mysql_query
(
&
mysql
,
"show tables"
,
0
)
||
!
(
*
cur_table_res
=
mc_mysql_store_result
(
&
mysql
)))
{
net_printf
(
&
thd
->
net
,
error
=
ER_QUERY_ON_MASTER
,
mc_mysql_error
(
&
mysql
));
cleanup_mysql_results
(
db_res
,
cur_table_res
-
1
,
table_res
);
goto
err
;
}
if
((
error
=
fetch_db_tables
(
thd
,
&
mysql
,
db
,
*
cur_table_res
)))
{
// we do not report the error - fetch_db_tables handles it
cleanup_mysql_results
(
db_res
,
cur_table_res
,
table_res
);
goto
err
;
}
}
cleanup_mysql_results
(
db_res
,
cur_table_res
-
1
,
table_res
);
// adjust position in the master
if
(
master_status_res
)
{
MYSQL_ROW
row
=
mc_mysql_fetch_row
(
master_status_res
);
// we need this check because the master may not be running with
// log-bin, but it will still allow us to do all the steps
// of LOAD DATA FROM MASTER - no reason to forbid it, really,
// although it does not make much sense for the user to do it
if
(
row
[
0
]
&&
row
[
1
])
{
strmake
(
glob_mi
.
log_file_name
,
row
[
0
],
sizeof
(
glob_mi
.
log_file_name
));
glob_mi
.
pos
=
atoi
(
row
[
1
]);
// atoi() is ok, since offset is <= 1GB
if
(
glob_mi
.
pos
<
4
)
glob_mi
.
pos
=
4
;
// don't hit the magic number
glob_mi
.
pending
=
0
;
flush_master_info
(
&
glob_mi
);
}
mc_mysql_free_result
(
master_status_res
);
}
if
(
mc_mysql_query
(
&
mysql
,
"UNLOCK TABLES"
,
0
))
{
net_printf
(
&
thd
->
net
,
error
=
ER_QUERY_ON_MASTER
,
mc_mysql_error
(
&
mysql
));
goto
err
;
}
}
err:
pthread_mutex_unlock
(
&
LOCK_slave
);
if
(
slave_was_running
)
start_slave
(
0
,
0
);
mc_mysql_close
(
&
mysql
);
// safe to call since we always do mc_mysql_init()
if
(
!
error
)
send_ok
(
&
thd
->
net
);
return
error
;
}
sql/sql_repl.h
View file @
73e6a690
...
...
@@ -14,6 +14,8 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
int
start_slave
(
THD
*
thd
=
0
,
bool
net_report
=
1
);
int
stop_slave
(
THD
*
thd
=
0
,
bool
net_report
=
1
);
int
load_master_data
(
THD
*
thd
);
int
connect_to_master
(
THD
*
thd
,
MYSQL
*
mysql
,
MASTER_INFO
*
mi
);
int
change_master
(
THD
*
thd
);
void
reset_slave
();
void
reset_master
();
...
...
sql/sql_yacc.yy
View file @
73e6a690
...
...
@@ -2401,6 +2401,11 @@ load: LOAD DATA_SYM opt_low_priority opt_local INFILE TEXT_STRING
YYABORT;
}
|
LOAD DATA_SYM FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
}
opt_local:
/* empty */ { $$=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