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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
8f6b34f9
Commit
8f6b34f9
authored
May 28, 2001
by
sasha@mysql.sashanet.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updates for LOAD DATA FROM MASTER + some cleanup of replication code
parent
8a3f87ab
Changes
18
Show 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 @
8f6b34f9
...
@@ -205,4 +205,6 @@
...
@@ -205,4 +205,6 @@
#define ER_SLAVE_THREAD 1202
#define ER_SLAVE_THREAD 1202
#define ER_TOO_MANY_USER_CONNECTIONS 1203
#define ER_TOO_MANY_USER_CONNECTIONS 1203
#define ER_SET_CONSTANTS_ONLY 1204
#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 @
8f6b34f9
n m
n m
4 15
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 @
8f6b34f9
...
@@ -31,3 +31,56 @@ connection slave;
...
@@ -31,3 +31,56 @@ connection slave;
sync_with_master
;
sync_with_master
;
drop
database
if
exists
bar
;
drop
database
if
exists
bar
;
drop
database
if
exists
foo
;
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 @
8f6b34f9
...
@@ -69,9 +69,22 @@ extern "C" { // Because of SCO 3.2V4.2
...
@@ -69,9 +69,22 @@ extern "C" { // Because of SCO 3.2V4.2
}
}
static
void
mc_free_rows
(
MYSQL_DATA
*
cur
);
static
MYSQL_FIELD
*
unpack_fields
(
MYSQL_DATA
*
data
,
MEM_ROOT
*
alloc
,
uint
fields
,
my_bool
default_value
,
my_bool
long_flag_protocol
);
static
void
mc_end_server
(
MYSQL
*
mysql
);
static
void
mc_end_server
(
MYSQL
*
mysql
);
static
int
mc_sock_connect
(
File
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
);
static
int
mc_sock_connect
(
File
s
,
const
struct
sockaddr
*
name
,
uint
namelen
,
uint
to
);
static
void
mc_free_old_query
(
MYSQL
*
mysql
);
static
void
mc_free_old_query
(
MYSQL
*
mysql
);
static
int
mc_send_file_to_server
(
MYSQL
*
mysql
,
const
char
*
filename
);
static
my_ulonglong
mc_net_field_length_ll
(
uchar
**
packet
);
static
ulong
mc_net_field_length
(
uchar
**
packet
);
static
int
mc_read_one_row
(
MYSQL
*
mysql
,
uint
fields
,
MYSQL_ROW
row
,
ulong
*
lengths
);
static
MYSQL_DATA
*
mc_read_rows
(
MYSQL
*
mysql
,
MYSQL_FIELD
*
mysql_fields
,
uint
fields
);
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
...
@@ -824,3 +837,498 @@ mc_mysql_close(MYSQL *mysql)
...
@@ -824,3 +837,498 @@ mc_mysql_close(MYSQL *mysql)
}
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
void
STDCALL
mc_mysql_free_result
(
MYSQL_RES
*
result
)
{
DBUG_ENTER
(
"mc_mysql_free_result"
);
DBUG_PRINT
(
"enter"
,(
"mysql_res: %lx"
,
result
));
if
(
result
)
{
if
(
result
->
handle
&&
result
->
handle
->
status
==
MYSQL_STATUS_USE_RESULT
)
{
DBUG_PRINT
(
"warning"
,(
"Not all rows in set were read; Ignoring rows"
));
for
(;;)
{
uint
pkt_len
;
if
((
pkt_len
=
(
uint
)
mc_net_safe_read
(
result
->
handle
))
==
packet_error
)
break
;
if
(
pkt_len
==
1
&&
result
->
handle
->
net
.
read_pos
[
0
]
==
254
)
break
;
/* End of data */
}
result
->
handle
->
status
=
MYSQL_STATUS_READY
;
}
mc_free_rows
(
result
->
data
);
if
(
result
->
fields
)
free_root
(
&
result
->
field_alloc
,
MYF
(
0
));
if
(
result
->
row
)
my_free
((
gptr
)
result
->
row
,
MYF
(
0
));
my_free
((
gptr
)
result
,
MYF
(
0
));
}
DBUG_VOID_RETURN
;
}
static
void
mc_free_rows
(
MYSQL_DATA
*
cur
)
{
if
(
cur
)
{
free_root
(
&
cur
->
alloc
,
MYF
(
0
));
my_free
((
gptr
)
cur
,
MYF
(
0
));
}
}
static
MYSQL_FIELD
*
mc_unpack_fields
(
MYSQL_DATA
*
data
,
MEM_ROOT
*
alloc
,
uint
fields
,
my_bool
default_value
,
my_bool
long_flag_protocol
)
{
MYSQL_ROWS
*
row
;
MYSQL_FIELD
*
field
,
*
result
;
DBUG_ENTER
(
"unpack_fields"
);
field
=
result
=
(
MYSQL_FIELD
*
)
alloc_root
(
alloc
,
sizeof
(
MYSQL_FIELD
)
*
fields
);
if
(
!
result
)
DBUG_RETURN
(
0
);
for
(
row
=
data
->
data
;
row
;
row
=
row
->
next
,
field
++
)
{
field
->
table
=
strdup_root
(
alloc
,(
char
*
)
row
->
data
[
0
]);
field
->
name
=
strdup_root
(
alloc
,(
char
*
)
row
->
data
[
1
]);
field
->
length
=
(
uint
)
uint3korr
(
row
->
data
[
2
]);
field
->
type
=
(
enum
enum_field_types
)
(
uchar
)
row
->
data
[
3
][
0
];
if
(
long_flag_protocol
)
{
field
->
flags
=
uint2korr
(
row
->
data
[
4
]);
field
->
decimals
=
(
uint
)
(
uchar
)
row
->
data
[
4
][
2
];
}
else
{
field
->
flags
=
(
uint
)
(
uchar
)
row
->
data
[
4
][
0
];
field
->
decimals
=
(
uint
)
(
uchar
)
row
->
data
[
4
][
1
];
}
if
(
INTERNAL_NUM_FIELD
(
field
))
field
->
flags
|=
NUM_FLAG
;
if
(
default_value
&&
row
->
data
[
5
])
field
->
def
=
strdup_root
(
alloc
,(
char
*
)
row
->
data
[
5
]);
else
field
->
def
=
0
;
field
->
max_length
=
0
;
}
mc_free_rows
(
data
);
/* Free old data */
DBUG_RETURN
(
result
);
}
int
STDCALL
mc_mysql_send_query
(
MYSQL
*
mysql
,
const
char
*
query
,
uint
length
)
{
return
mc_simple_command
(
mysql
,
COM_QUERY
,
query
,
length
,
1
);
}
int
STDCALL
mc_mysql_read_query_result
(
MYSQL
*
mysql
)
{
uchar
*
pos
;
ulong
field_count
;
MYSQL_DATA
*
fields
;
uint
length
;
DBUG_ENTER
(
"mc_mysql_read_query_result"
);
if
((
length
=
mc_net_safe_read
(
mysql
))
==
packet_error
)
DBUG_RETURN
(
-
1
);
mc_free_old_query
(
mysql
);
/* Free old result */
get_info:
pos
=
(
uchar
*
)
mysql
->
net
.
read_pos
;
if
((
field_count
=
mc_net_field_length
(
&
pos
))
==
0
)
{
mysql
->
affected_rows
=
mc_net_field_length_ll
(
&
pos
);
mysql
->
insert_id
=
mc_net_field_length_ll
(
&
pos
);
if
(
mysql
->
server_capabilities
&
CLIENT_TRANSACTIONS
)
{
mysql
->
server_status
=
uint2korr
(
pos
);
pos
+=
2
;
}
if
(
pos
<
mysql
->
net
.
read_pos
+
length
&&
mc_net_field_length
(
&
pos
))
mysql
->
info
=
(
char
*
)
pos
;
DBUG_RETURN
(
0
);
}
if
(
field_count
==
NULL_LENGTH
)
/* LOAD DATA LOCAL INFILE */
{
int
error
=
mc_send_file_to_server
(
mysql
,(
char
*
)
pos
);
if
((
length
=
mc_net_safe_read
(
mysql
))
==
packet_error
||
error
)
DBUG_RETURN
(
-
1
);
goto
get_info
;
/* Get info packet */
}
if
(
!
(
mysql
->
server_status
&
SERVER_STATUS_AUTOCOMMIT
))
mysql
->
server_status
|=
SERVER_STATUS_IN_TRANS
;
mysql
->
extra_info
=
mc_net_field_length_ll
(
&
pos
);
/* Maybe number of rec */
if
(
!
(
fields
=
mc_read_rows
(
mysql
,(
MYSQL_FIELD
*
)
0
,
5
)))
DBUG_RETURN
(
-
1
);
if
(
!
(
mysql
->
fields
=
mc_unpack_fields
(
fields
,
&
mysql
->
field_alloc
,
(
uint
)
field_count
,
0
,
(
my_bool
)
test
(
mysql
->
server_capabilities
&
CLIENT_LONG_FLAG
))))
DBUG_RETURN
(
-
1
);
mysql
->
status
=
MYSQL_STATUS_GET_RESULT
;
mysql
->
field_count
=
field_count
;
DBUG_RETURN
(
0
);
}
int
STDCALL
mc_mysql_query
(
MYSQL
*
mysql
,
const
char
*
query
,
uint
length
)
{
DBUG_ENTER
(
"mysql_real_query"
);
DBUG_PRINT
(
"enter"
,(
"handle: %lx"
,
mysql
));
DBUG_PRINT
(
"query"
,(
"Query =
\"
%s
\"
"
,
query
));
if
(
!
length
)
length
=
strlen
(
query
);
if
(
mc_simple_command
(
mysql
,
COM_QUERY
,
query
,
length
,
1
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
mc_mysql_read_query_result
(
mysql
));
}
static
int
mc_send_file_to_server
(
MYSQL
*
mysql
,
const
char
*
filename
)
{
int
fd
,
readcount
;
char
buf
[
IO_SIZE
*
15
],
*
tmp_name
;
DBUG_ENTER
(
"send_file_to_server"
);
fn_format
(
buf
,
filename
,
""
,
""
,
4
);
/* Convert to client format */
if
(
!
(
tmp_name
=
my_strdup
(
buf
,
MYF
(
0
))))
{
strmov
(
mysql
->
net
.
last_error
,
ER
(
mysql
->
net
.
last_errno
=
CR_OUT_OF_MEMORY
));
DBUG_RETURN
(
-
1
);
}
if
((
fd
=
my_open
(
tmp_name
,
O_RDONLY
,
MYF
(
0
)))
<
0
)
{
mysql
->
net
.
last_errno
=
EE_FILENOTFOUND
;
sprintf
(
buf
,
EE
(
mysql
->
net
.
last_errno
),
tmp_name
,
errno
);
strmake
(
mysql
->
net
.
last_error
,
buf
,
sizeof
(
mysql
->
net
.
last_error
)
-
1
);
my_net_write
(
&
mysql
->
net
,
""
,
0
);
net_flush
(
&
mysql
->
net
);
my_free
(
tmp_name
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
while
((
readcount
=
(
int
)
my_read
(
fd
,
buf
,
sizeof
(
buf
),
MYF
(
0
)))
>
0
)
{
if
(
my_net_write
(
&
mysql
->
net
,
buf
,
readcount
))
{
mysql
->
net
.
last_errno
=
CR_SERVER_LOST
;
strmov
(
mysql
->
net
.
last_error
,
ER
(
mysql
->
net
.
last_errno
));
DBUG_PRINT
(
"error"
,(
"Lost connection to MySQL server during LOAD DATA of local file"
));
(
void
)
my_close
(
fd
,
MYF
(
0
));
my_free
(
tmp_name
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
}
(
void
)
my_close
(
fd
,
MYF
(
0
));
/* Send empty packet to mark end of file */
if
(
my_net_write
(
&
mysql
->
net
,
""
,
0
)
||
net_flush
(
&
mysql
->
net
))
{
mysql
->
net
.
last_errno
=
CR_SERVER_LOST
;
sprintf
(
mysql
->
net
.
last_error
,
ER
(
mysql
->
net
.
last_errno
),
errno
);
my_free
(
tmp_name
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
if
(
readcount
<
0
)
{
mysql
->
net
.
last_errno
=
EE_READ
;
/* the errmsg for not entire file read */
sprintf
(
buf
,
EE
(
mysql
->
net
.
last_errno
),
tmp_name
,
errno
);
strmake
(
mysql
->
net
.
last_error
,
buf
,
sizeof
(
mysql
->
net
.
last_error
)
-
1
);
my_free
(
tmp_name
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
}
/* Get the length of next field. Change parameter to point at fieldstart */
static
ulong
mc_net_field_length
(
uchar
**
packet
)
{
reg1
uchar
*
pos
=
*
packet
;
if
(
*
pos
<
251
)
{
(
*
packet
)
++
;
return
(
ulong
)
*
pos
;
}
if
(
*
pos
==
251
)
{
(
*
packet
)
++
;
return
NULL_LENGTH
;
}
if
(
*
pos
==
252
)
{
(
*
packet
)
+=
3
;
return
(
ulong
)
uint2korr
(
pos
+
1
);
}
if
(
*
pos
==
253
)
{
(
*
packet
)
+=
4
;
return
(
ulong
)
uint3korr
(
pos
+
1
);
}
(
*
packet
)
+=
9
;
/* Must be 254 when here */
return
(
ulong
)
uint4korr
(
pos
+
1
);
}
/* Same as above, but returns ulonglong values */
static
my_ulonglong
mc_net_field_length_ll
(
uchar
**
packet
)
{
reg1
uchar
*
pos
=
*
packet
;
if
(
*
pos
<
251
)
{
(
*
packet
)
++
;
return
(
my_ulonglong
)
*
pos
;
}
if
(
*
pos
==
251
)
{
(
*
packet
)
++
;
return
(
my_ulonglong
)
NULL_LENGTH
;
}
if
(
*
pos
==
252
)
{
(
*
packet
)
+=
3
;
return
(
my_ulonglong
)
uint2korr
(
pos
+
1
);
}
if
(
*
pos
==
253
)
{
(
*
packet
)
+=
4
;
return
(
my_ulonglong
)
uint3korr
(
pos
+
1
);
}
(
*
packet
)
+=
9
;
/* Must be 254 when here */
#ifdef NO_CLIENT_LONGLONG
return
(
my_ulonglong
)
uint4korr
(
pos
+
1
);
#else
return
(
my_ulonglong
)
uint8korr
(
pos
+
1
);
#endif
}
/* Read all rows (fields or data) from server */
static
MYSQL_DATA
*
mc_read_rows
(
MYSQL
*
mysql
,
MYSQL_FIELD
*
mysql_fields
,
uint
fields
)
{
uint
field
,
pkt_len
;
ulong
len
;
uchar
*
cp
;
char
*
to
;
MYSQL_DATA
*
result
;
MYSQL_ROWS
**
prev_ptr
,
*
cur
;
NET
*
net
=
&
mysql
->
net
;
DBUG_ENTER
(
"mc_read_rows"
);
if
((
pkt_len
=
(
uint
)
mc_net_safe_read
(
mysql
))
==
packet_error
)
DBUG_RETURN
(
0
);
if
(
!
(
result
=
(
MYSQL_DATA
*
)
my_malloc
(
sizeof
(
MYSQL_DATA
),
MYF
(
MY_WME
|
MY_ZEROFILL
))))
{
net
->
last_errno
=
CR_OUT_OF_MEMORY
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
DBUG_RETURN
(
0
);
}
init_alloc_root
(
&
result
->
alloc
,
8192
,
0
);
/* Assume rowlength < 8192 */
result
->
alloc
.
min_malloc
=
sizeof
(
MYSQL_ROWS
);
prev_ptr
=
&
result
->
data
;
result
->
rows
=
0
;
result
->
fields
=
fields
;
while
(
*
(
cp
=
net
->
read_pos
)
!=
254
||
pkt_len
!=
1
)
{
result
->
rows
++
;
if
(
!
(
cur
=
(
MYSQL_ROWS
*
)
alloc_root
(
&
result
->
alloc
,
sizeof
(
MYSQL_ROWS
)))
||
!
(
cur
->
data
=
((
MYSQL_ROW
)
alloc_root
(
&
result
->
alloc
,
(
fields
+
1
)
*
sizeof
(
char
*
)
+
pkt_len
))))
{
mc_free_rows
(
result
);
net
->
last_errno
=
CR_OUT_OF_MEMORY
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
DBUG_RETURN
(
0
);
}
*
prev_ptr
=
cur
;
prev_ptr
=
&
cur
->
next
;
to
=
(
char
*
)
(
cur
->
data
+
fields
+
1
);
for
(
field
=
0
;
field
<
fields
;
field
++
)
{
if
((
len
=
(
ulong
)
mc_net_field_length
(
&
cp
))
==
NULL_LENGTH
)
{
/* null field */
cur
->
data
[
field
]
=
0
;
}
else
{
cur
->
data
[
field
]
=
to
;
memcpy
(
to
,(
char
*
)
cp
,
len
);
to
[
len
]
=
0
;
to
+=
len
+
1
;
cp
+=
len
;
if
(
mysql_fields
)
{
if
(
mysql_fields
[
field
].
max_length
<
len
)
mysql_fields
[
field
].
max_length
=
len
;
}
}
}
cur
->
data
[
field
]
=
to
;
/* End of last field */
if
((
pkt_len
=
mc_net_safe_read
(
mysql
))
==
packet_error
)
{
mc_free_rows
(
result
);
DBUG_RETURN
(
0
);
}
}
*
prev_ptr
=
0
;
/* last pointer is null */
DBUG_PRINT
(
"exit"
,(
"Got %d rows"
,
result
->
rows
));
DBUG_RETURN
(
result
);
}
/*
** Read one row. Uses packet buffer as storage for fields.
** When next packet is read, the previous field values are destroyed
*/
static
int
mc_read_one_row
(
MYSQL
*
mysql
,
uint
fields
,
MYSQL_ROW
row
,
ulong
*
lengths
)
{
uint
field
;
ulong
pkt_len
,
len
;
uchar
*
pos
,
*
prev_pos
;
if
((
pkt_len
=
(
uint
)
mc_net_safe_read
(
mysql
))
==
packet_error
)
return
-
1
;
if
(
pkt_len
==
1
&&
mysql
->
net
.
read_pos
[
0
]
==
254
)
return
1
;
/* End of data */
prev_pos
=
0
;
/* allowed to write at packet[-1] */
pos
=
mysql
->
net
.
read_pos
;
for
(
field
=
0
;
field
<
fields
;
field
++
)
{
if
((
len
=
(
ulong
)
mc_net_field_length
(
&
pos
))
==
NULL_LENGTH
)
{
/* null field */
row
[
field
]
=
0
;
*
lengths
++=
0
;
}
else
{
row
[
field
]
=
(
char
*
)
pos
;
pos
+=
len
;
*
lengths
++=
len
;
}
if
(
prev_pos
)
*
prev_pos
=
0
;
/* Terminate prev field */
prev_pos
=
pos
;
}
row
[
field
]
=
(
char
*
)
prev_pos
+
1
;
/* End of last field */
*
prev_pos
=
0
;
/* Terminate last field */
return
0
;
}
my_ulonglong
STDCALL
mc_mysql_num_rows
(
MYSQL_RES
*
res
)
{
return
res
->
row_count
;
}
unsigned
int
STDCALL
mc_mysql_num_fields
(
MYSQL_RES
*
res
)
{
return
res
->
field_count
;
}
void
STDCALL
mc_mysql_data_seek
(
MYSQL_RES
*
result
,
my_ulonglong
row
)
{
MYSQL_ROWS
*
tmp
=
0
;
DBUG_PRINT
(
"info"
,(
"mysql_data_seek(%ld)"
,(
long
)
row
));
if
(
result
->
data
)
for
(
tmp
=
result
->
data
->
data
;
row
--
&&
tmp
;
tmp
=
tmp
->
next
)
;
result
->
current_row
=
0
;
result
->
data_cursor
=
tmp
;
}
MYSQL_ROW
STDCALL
mc_mysql_fetch_row
(
MYSQL_RES
*
res
)
{
DBUG_ENTER
(
"mc_mysql_fetch_row"
);
if
(
!
res
->
data
)
{
/* Unbufferred fetch */
if
(
!
res
->
eof
)
{
if
(
!
(
mc_read_one_row
(
res
->
handle
,
res
->
field_count
,
res
->
row
,
res
->
lengths
)))
{
res
->
row_count
++
;
DBUG_RETURN
(
res
->
current_row
=
res
->
row
);
}
else
{
DBUG_PRINT
(
"info"
,(
"end of data"
));
res
->
eof
=
1
;
res
->
handle
->
status
=
MYSQL_STATUS_READY
;
}
}
DBUG_RETURN
((
MYSQL_ROW
)
NULL
);
}
{
MYSQL_ROW
tmp
;
if
(
!
res
->
data_cursor
)
{
DBUG_PRINT
(
"info"
,(
"end of data"
));
DBUG_RETURN
(
res
->
current_row
=
(
MYSQL_ROW
)
NULL
);
}
tmp
=
res
->
data_cursor
->
data
;
res
->
data_cursor
=
res
->
data_cursor
->
next
;
DBUG_RETURN
(
res
->
current_row
=
tmp
);
}
}
int
STDCALL
mc_mysql_select_db
(
MYSQL
*
mysql
,
const
char
*
db
)
{
int
error
;
DBUG_ENTER
(
"mysql_select_db"
);
DBUG_PRINT
(
"enter"
,(
"db: '%s'"
,
db
));
if
((
error
=
mc_simple_command
(
mysql
,
COM_INIT_DB
,
db
,(
uint
)
strlen
(
db
),
0
)))
DBUG_RETURN
(
error
);
my_free
(
mysql
->
db
,
MYF
(
MY_ALLOW_ZERO_PTR
));
mysql
->
db
=
my_strdup
(
db
,
MYF
(
MY_WME
));
DBUG_RETURN
(
0
);
}
MYSQL_RES
*
STDCALL
mc_mysql_store_result
(
MYSQL
*
mysql
)
{
MYSQL_RES
*
result
;
DBUG_ENTER
(
"mysql_store_result"
);
if
(
!
mysql
->
fields
)
DBUG_RETURN
(
0
);
if
(
mysql
->
status
!=
MYSQL_STATUS_GET_RESULT
)
{
strmov
(
mysql
->
net
.
last_error
,
ER
(
mysql
->
net
.
last_errno
=
CR_COMMANDS_OUT_OF_SYNC
));
DBUG_RETURN
(
0
);
}
mysql
->
status
=
MYSQL_STATUS_READY
;
/* server is ready */
if
(
!
(
result
=
(
MYSQL_RES
*
)
my_malloc
(
sizeof
(
MYSQL_RES
)
+
sizeof
(
ulong
)
*
mysql
->
field_count
,
MYF
(
MY_WME
|
MY_ZEROFILL
))))
{
mysql
->
net
.
last_errno
=
CR_OUT_OF_MEMORY
;
strmov
(
mysql
->
net
.
last_error
,
ER
(
mysql
->
net
.
last_errno
));
DBUG_RETURN
(
0
);
}
result
->
eof
=
1
;
/* Marker for buffered */
result
->
lengths
=
(
ulong
*
)
(
result
+
1
);
if
(
!
(
result
->
data
=
mc_read_rows
(
mysql
,
mysql
->
fields
,
mysql
->
field_count
)))
{
my_free
((
gptr
)
result
,
MYF
(
0
));
DBUG_RETURN
(
0
);
}
mysql
->
affected_rows
=
result
->
row_count
=
result
->
data
->
rows
;
result
->
data_cursor
=
result
->
data
->
data
;
result
->
fields
=
mysql
->
fields
;
result
->
field_alloc
=
mysql
->
field_alloc
;
result
->
field_count
=
mysql
->
field_count
;
result
->
current_field
=
0
;
result
->
current_row
=
0
;
/* Must do a fetch first */
mysql
->
fields
=
0
;
/* fields is now in result */
DBUG_RETURN
(
result
);
/* Data fetched */
}
sql/mini_client.h
View file @
8f6b34f9
...
@@ -42,6 +42,17 @@ char * STDCALL mc_mysql_error(MYSQL *mysql);
...
@@ -42,6 +42,17 @@ char * STDCALL mc_mysql_error(MYSQL *mysql);
int
STDCALL
mc_mysql_errno
(
MYSQL
*
mysql
);
int
STDCALL
mc_mysql_errno
(
MYSQL
*
mysql
);
my_bool
STDCALL
mc_mysql_reconnect
(
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
#endif
sql/mysql_priv.h
View file @
8f6b34f9
...
@@ -223,7 +223,7 @@ inline THD *_current_thd(void)
...
@@ -223,7 +223,7 @@ inline THD *_current_thd(void)
#include "opt_range.h"
#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
);
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
mysql_rm_table
(
THD
*
thd
,
TABLE_LIST
*
tables
,
my_bool
if_exists
);
int
quick_rm_table
(
enum
db_type
base
,
const
char
*
db
,
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,
...
@@ -245,7 +245,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char
*
packet
,
uint
packet_length
);
char
*
packet
,
uint
packet_length
);
bool
check_stack_overrun
(
THD
*
thd
,
char
*
dummy
);
bool
check_stack_overrun
(
THD
*
thd
,
char
*
dummy
);
bool
reload_acl_and_cache
(
THD
*
thd
,
uint
options
,
TABLE_LIST
*
tables
);
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_init
(
void
);
void
table_cache_free
(
void
);
void
table_cache_free
(
void
);
uint
cached_tables
(
void
);
uint
cached_tables
(
void
);
...
...
sql/share/english/errmsg.txt
View file @
8f6b34f9
...
@@ -153,7 +153,7 @@
...
@@ -153,7 +153,7 @@
"You have an error in your SQL syntax",
"You have an error in your SQL syntax",
"Delayed insert thread couldn't get requested lock for table %-.64s",
"Delayed insert thread couldn't get requested lock for table %-.64s",
"Too many delayed threads in use",
"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 packet bigger than 'max_allowed_packet'",
"Got a read error from the connection pipe",
"Got a read error from the connection pipe",
"Got an error from fcntl()",
"Got an error from fcntl()",
...
@@ -185,7 +185,7 @@
...
@@ -185,7 +185,7 @@
"Got error %d during ROLLBACK",
"Got error %d during ROLLBACK",
"Got error %d during FLUSH_LOGS",
"Got error %d during FLUSH_LOGS",
"Got error %d during CHECKPOINT",
"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",
"The handler for the table does not support binary table dump",
"Binlog closed, cannot RESET MASTER",
"Binlog closed, cannot RESET MASTER",
"Failed rebuilding the index of dumped table '%-.64s'",
"Failed rebuilding the index of dumped table '%-.64s'",
...
@@ -206,3 +206,8 @@
...
@@ -206,3 +206,8 @@
"Could not create slave thread, check system resources",
"Could not create slave thread, check system resources",
"User %-.64s has already more than 'max_user_connections' active connections",
"User %-.64s has already more than 'max_user_connections' active connections",
"You may only use constant expressions with SET",
"You may only use constant expressions with SET",
"Error connecting to master: %-.128s",
"Error running query on master: %-.128s",
sql/slave.cc
View file @
8f6b34f9
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <myisam.h>
#include <myisam.h>
#include "mini_client.h"
#include "mini_client.h"
#include "slave.h"
#include "slave.h"
#include "sql_repl.h"
#include <thr_alarm.h>
#include <thr_alarm.h>
#include <my_dir.h>
#include <my_dir.h>
...
@@ -55,7 +56,7 @@ static int init_slave_thread(THD* thd);
...
@@ -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_connect
(
THD
*
thd
,
MYSQL
*
mysql
,
MASTER_INFO
*
mi
);
static
int
safe_reconnect
(
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
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
,
static
int
create_table_from_dump
(
THD
*
thd
,
NET
*
net
,
const
char
*
db
,
const
char
*
table_name
);
const
char
*
table_name
);
inline
char
*
rewrite_db
(
char
*
db
);
inline
char
*
rewrite_db
(
char
*
db
);
...
@@ -344,7 +345,7 @@ static int create_table_from_dump(THD* thd, NET* net, const 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"
;
thd
->
proc_info
=
"Creating table from master dump"
;
// save old db in case we are creating in a different database
// save old db in case we are creating in a different database
char
*
save_db
=
thd
->
db
;
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
mysql_parse
(
thd
,
thd
->
query
,
packet_len
);
// run create table
thd
->
db
=
save_db
;
// leave things the way the were before
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,
...
@@ -400,31 +401,39 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
return
error
;
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
error
=
1
;
int
nx_errno
=
0
;
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()"
);
sql_print_error
(
"fetch_nx_table: Error in mysql_init()"
);
nx_errno
=
ER_GET_ERRNO
;
nx_errno
=
ER_GET_ERRNO
;
goto
err
;
goto
err
;
}
}
safe_connect
(
thd
,
mysql
,
mi
);
if
(
!
called_connected
)
if
(
slave_killed
(
thd
))
{
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
;
goto
err
;
}
}
if
(
request_table_dump
(
mysql
,
thd
->
last_nx_db
,
thd
->
last_nx_tabl
e
))
if
(
request_table_dump
(
mysql
,
db_name
,
table_nam
e
))
{
{
nx_errno
=
ER_GET_ERRNO
;
nx_errno
=
ER_GET_ERRNO
;
sql_print_error
(
"fetch_nx_table: failed on table dump request "
);
sql_print_error
(
"fetch_nx_table: failed on table dump request "
);
goto
err
;
goto
err
;
}
}
if
(
create_table_from_dump
(
thd
,
&
mysql
->
net
,
thd
->
last_nx_db
,
if
(
create_table_from_dump
(
thd
,
&
mysql
->
net
,
db_name
,
t
hd
->
last_nx_tabl
e
))
t
able_nam
e
))
{
{
// create_table_from_dump will have sent the error alread
// create_table_from_dump will have sent the error alread
sql_print_error
(
"fetch_nx_table: failed on create table "
);
sql_print_error
(
"fetch_nx_table: failed on create table "
);
...
@@ -434,7 +443,7 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi)
...
@@ -434,7 +443,7 @@ int fetch_nx_table(THD* thd, MASTER_INFO* mi)
error
=
0
;
error
=
0
;
err:
err:
if
(
mysql
)
if
(
mysql
&&
!
called_connected
)
mc_mysql_close
(
mysql
);
mc_mysql_close
(
mysql
);
if
(
nx_errno
&&
thd
->
net
.
vio
)
if
(
nx_errno
&&
thd
->
net
.
vio
)
send_error
(
&
thd
->
net
,
nx_errno
,
"Error in fetch_nx_table"
);
send_error
(
&
thd
->
net
,
nx_errno
,
"Error in fetch_nx_table"
);
...
@@ -764,7 +773,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
...
@@ -764,7 +773,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
return
0
;
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
buf
[
1024
];
char
*
p
=
buf
;
char
*
p
=
buf
;
...
@@ -901,7 +910,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
...
@@ -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
));
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
query_id
=
query_id
++
;
thd
->
query_id
=
query_id
++
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
thd
->
last_nx_table
=
thd
->
last_nx_db
=
0
;
thd
->
query_error
=
0
;
// clear error
thd
->
query_error
=
0
;
// clear error
thd
->
net
.
last_errno
=
0
;
thd
->
net
.
last_errno
=
0
;
thd
->
net
.
last_error
[
0
]
=
0
;
thd
->
net
.
last_error
[
0
]
=
0
;
...
...
sql/slave.h
View file @
8f6b34f9
#ifndef SLAVE_H
#ifndef SLAVE_H
#define SLAVE_H
#define SLAVE_H
#include "mysql.h"
typedef
struct
st_master_info
typedef
struct
st_master_info
{
{
char
log_file_name
[
FN_REFLEN
];
char
log_file_name
[
FN_REFLEN
];
...
@@ -65,11 +67,14 @@ typedef struct st_table_rule_ent
...
@@ -65,11 +67,14 @@ typedef struct st_table_rule_ent
int
flush_master_info
(
MASTER_INFO
*
mi
);
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
// 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
// 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_master_info
(
THD
*
thd
);
int
show_binlog_info
(
THD
*
thd
);
int
show_binlog_info
(
THD
*
thd
);
...
...
sql/sql_base.cc
View file @
8f6b34f9
...
@@ -837,25 +837,6 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
...
@@ -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
,
!
(
table
->
table_cache_key
=
memdup_root
(
&
table
->
mem_root
,(
char
*
)
key
,
key_length
)))
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
;
table
->
next
=
table
->
prev
=
table
;
free_cache_entry
(
table
);
free_cache_entry
(
table
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
...
...
sql/sql_class.cc
View file @
8f6b34f9
...
@@ -96,7 +96,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
...
@@ -96,7 +96,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
current_linfo
=
0
;
current_linfo
=
0
;
slave_thread
=
0
;
slave_thread
=
0
;
slave_proxy_id
=
0
;
slave_proxy_id
=
0
;
last_nx_table
=
last_nx_db
=
0
;
cond_count
=
0
;
cond_count
=
0
;
convert_set
=
0
;
convert_set
=
0
;
mysys_var
=
0
;
mysys_var
=
0
;
...
...
sql/sql_class.h
View file @
8f6b34f9
...
@@ -242,8 +242,6 @@ public:
...
@@ -242,8 +242,6 @@ public:
enum
enum_server_command
command
;
enum
enum_server_command
command
;
uint32
server_id
;
uint32
server_id
;
const
char
*
where
;
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
start_time
,
time_after_lock
,
user_time
;
time_t
connect_time
,
thr_create_time
;
// track down slow pthread_create
time_t
connect_time
,
thr_create_time
;
// track down slow pthread_create
thr_lock_type
update_lock_default
;
thr_lock_type
update_lock_default
;
...
...
sql/sql_db.cc
View file @
8f6b34f9
...
@@ -30,11 +30,12 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
...
@@ -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 */
/* 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
];
char
path
[
FN_REFLEN
+
16
];
MY_DIR
*
dirp
;
MY_DIR
*
dirp
;
long
result
=
1
;
long
result
=
1
;
int
error
=
0
;
DBUG_ENTER
(
"mysql_create_db"
);
DBUG_ENTER
(
"mysql_create_db"
);
VOID
(
pthread_mutex_lock
(
&
LOCK_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)
...
@@ -47,7 +48,9 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
my_dirend
(
dirp
);
my_dirend
(
dirp
);
if
(
!
(
create_options
&
HA_LEX_CREATE_IF_NOT_EXISTS
))
if
(
!
(
create_options
&
HA_LEX_CREATE_IF_NOT_EXISTS
))
{
{
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_CREATE_EXISTS
,
db
);
net_printf
(
&
thd
->
net
,
ER_DB_CREATE_EXISTS
,
db
);
error
=
1
;
goto
exit
;
goto
exit
;
}
}
result
=
0
;
result
=
0
;
...
@@ -57,10 +60,15 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
...
@@ -57,10 +60,15 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
strend
(
path
)[
-
1
]
=
0
;
// Remove last '/' from path
strend
(
path
)[
-
1
]
=
0
;
// Remove last '/' from path
if
(
my_mkdir
(
path
,
0777
,
MYF
(
0
))
<
0
)
if
(
my_mkdir
(
path
,
0777
,
MYF
(
0
))
<
0
)
{
{
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_CANT_CREATE_DB
,
db
,
my_errno
);
net_printf
(
&
thd
->
net
,
ER_CANT_CREATE_DB
,
db
,
my_errno
);
error
=
1
;
goto
exit
;
goto
exit
;
}
}
}
}
if
(
thd
)
{
if
(
!
thd
->
query
)
if
(
!
thd
->
query
)
{
{
thd
->
query
=
path
;
thd
->
query
=
path
;
...
@@ -81,10 +89,10 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
...
@@ -81,10 +89,10 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
thd
->
query_length
=
0
;
thd
->
query_length
=
0
;
}
}
send_ok
(
&
thd
->
net
,
result
);
send_ok
(
&
thd
->
net
,
result
);
}
exit:
exit:
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
error
)
;
}
}
const
char
*
del_exts
[]
=
const
char
*
del_exts
[]
=
...
@@ -94,10 +102,14 @@ static TYPELIB deletable_extentions=
...
@@ -94,10 +102,14 @@ static TYPELIB deletable_extentions=
/* db-name is already validated when we come here */
/* db-name is already validated when we come here */
/* If thd == 0, do not write any messages
void
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
)
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
;
long
deleted
=
0
;
int
error
=
0
;
char
path
[
FN_REFLEN
+
16
];
char
path
[
FN_REFLEN
+
16
];
MY_DIR
*
dirp
;
MY_DIR
*
dirp
;
DBUG_ENTER
(
"mysql_rm_db"
);
DBUG_ENTER
(
"mysql_rm_db"
);
...
@@ -109,16 +121,20 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
...
@@ -109,16 +121,20 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
unpack_dirname
(
path
,
path
);
// Convert if not unix
unpack_dirname
(
path
,
path
);
// Convert if not unix
/* See if the directory exists */
/* See if the directory exists */
if
(
!
(
dirp
=
my_dir
(
path
,
MYF
(
MY_WME
|
MY_DONT_SORT
))))
if
(
!
(
dirp
=
my_dir
(
path
,
MYF
(
MY_WME
|
MY_DONT_SORT
))))
{
if
(
thd
)
{
{
if
(
!
if_exists
)
if
(
!
if_exists
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_EXISTS
,
db
);
net_printf
(
&
thd
->
net
,
ER_DB_DROP_EXISTS
,
db
);
else
else
send_ok
(
&
thd
->
net
,
0
);
send_ok
(
&
thd
->
net
,
0
);
}
error
=
!
if_exists
;
goto
exit
;
goto
exit
;
}
}
remove_db_from_cache
(
db
);
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
)
if
(
!
thd
->
query
)
{
{
...
@@ -137,13 +153,14 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
...
@@ -137,13 +153,14 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
thd
->
query
=
0
;
// just in case
thd
->
query
=
0
;
// just in case
thd
->
query_length
=
0
;
thd
->
query_length
=
0
;
}
}
send_ok
(
&
thd
->
net
,(
ulong
)
deleted
);
send_ok
(
&
thd
->
net
,(
ulong
)
deleted
);
}
}
exit:
exit:
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_mysql_create_db
));
DBUG_
VOID_RETURN
;
DBUG_
RETURN
(
error
)
;
}
}
/*
/*
...
@@ -151,6 +168,7 @@ exit:
...
@@ -151,6 +168,7 @@ exit:
are 2 digits (raid directories).
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
,
static
long
mysql_rm_known_files
(
THD
*
thd
,
MY_DIR
*
dirp
,
const
char
*
org_path
,
uint
level
)
uint
level
)
{
{
...
@@ -162,7 +180,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
...
@@ -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 */
/* remove all files with known extensions */
for
(
uint
idx
=
2
;
for
(
uint
idx
=
2
;
idx
<
(
uint
)
dirp
->
number_off_files
&&
!
thd
->
killed
;
idx
<
(
uint
)
dirp
->
number_off_files
&&
(
!
thd
||
!
thd
->
killed
)
;
idx
++
)
idx
++
)
{
{
FILEINFO
*
file
=
dirp
->
dir_entry
+
idx
;
FILEINFO
*
file
=
dirp
->
dir_entry
+
idx
;
...
@@ -196,6 +214,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
...
@@ -196,6 +214,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
unpack_filename
(
filePath
,
filePath
);
unpack_filename
(
filePath
,
filePath
);
if
(
my_delete
(
filePath
,
MYF
(
MY_WME
)))
if
(
my_delete
(
filePath
,
MYF
(
MY_WME
)))
{
{
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_DELETE
,
filePath
,
my_error
);
net_printf
(
&
thd
->
net
,
ER_DB_DROP_DELETE
,
filePath
,
my_error
);
my_dirend
(
dirp
);
my_dirend
(
dirp
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
@@ -205,7 +224,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
...
@@ -205,7 +224,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
my_dirend
(
dirp
);
my_dirend
(
dirp
);
if
(
thd
->
killed
)
if
(
thd
&&
thd
->
killed
)
{
{
send_error
(
&
thd
->
net
,
ER_SERVER_SHUTDOWN
);
send_error
(
&
thd
->
net
,
ER_SERVER_SHUTDOWN
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
@@ -229,6 +248,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
...
@@ -229,6 +248,7 @@ 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 */
/* Don't give errors if we can't delete 'RAID' directory */
if
(
level
)
if
(
level
)
DBUG_RETURN
(
deleted
);
DBUG_RETURN
(
deleted
);
if
(
thd
)
send_error
(
&
thd
->
net
);
send_error
(
&
thd
->
net
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
@@ -242,6 +262,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path,
...
@@ -242,6 +262,7 @@ 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 */
/* Don't give errors if we can't delete 'RAID' directory */
if
(
rmdir
(
path
)
<
0
&&
!
level
)
if
(
rmdir
(
path
)
<
0
&&
!
level
)
{
{
if
(
thd
)
net_printf
(
&
thd
->
net
,
ER_DB_DROP_RMDIR
,
path
,
errno
);
net_printf
(
&
thd
->
net
,
ER_DB_DROP_RMDIR
,
path
,
errno
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
...
sql/sql_lex.h
View file @
8f6b34f9
...
@@ -53,7 +53,7 @@ enum enum_sql_command {
...
@@ -53,7 +53,7 @@ enum enum_sql_command {
SQLCOM_BEGIN
,
SQLCOM_LOAD_MASTER_TABLE
,
SQLCOM_CHANGE_MASTER
,
SQLCOM_BEGIN
,
SQLCOM_LOAD_MASTER_TABLE
,
SQLCOM_CHANGE_MASTER
,
SQLCOM_RENAME_TABLE
,
SQLCOM_BACKUP_TABLE
,
SQLCOM_RESTORE_TABLE
,
SQLCOM_RENAME_TABLE
,
SQLCOM_BACKUP_TABLE
,
SQLCOM_RESTORE_TABLE
,
SQLCOM_RESET
,
SQLCOM_PURGE
,
SQLCOM_SHOW_BINLOGS
,
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
SQLCOM_HA_OPEN
,
SQLCOM_HA_CLOSE
,
SQLCOM_HA_READ
};
};
...
...
sql/sql_parse.cc
View file @
8f6b34f9
...
@@ -1203,6 +1203,13 @@ mysql_execute_command(void)
...
@@ -1203,6 +1203,13 @@ mysql_execute_command(void)
res
=
show_binlog_info
(
thd
);
res
=
show_binlog_info
(
thd
);
break
;
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
:
case
SQLCOM_LOAD_MASTER_TABLE
:
if
(
!
tables
->
db
)
if
(
!
tables
->
db
)
...
@@ -1226,9 +1233,7 @@ mysql_execute_command(void)
...
@@ -1226,9 +1233,7 @@ mysql_execute_command(void)
break
;
break
;
}
}
thd
->
last_nx_table
=
tables
->
real_name
;
if
(
fetch_nx_table
(
thd
,
tables
->
db
,
tables
->
real_name
,
&
glob_mi
,
0
))
thd
->
last_nx_db
=
tables
->
db
;
if
(
fetch_nx_table
(
thd
,
&
glob_mi
))
// fetch_nx_table is responsible for sending
// fetch_nx_table is responsible for sending
// the error
// the error
{
{
...
...
sql/sql_repl.cc
View file @
8f6b34f9
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include "sql_repl.h"
#include "sql_repl.h"
#include "sql_acl.h"
#include "sql_acl.h"
#include "log_event.h"
#include "log_event.h"
#include "mini_client.h"
#include <thr_alarm.h>
#include <thr_alarm.h>
#include <my_dir.h>
#include <my_dir.h>
...
@@ -845,5 +846,220 @@ err:
...
@@ -845,5 +846,220 @@ err:
return
1
;
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 @
8f6b34f9
...
@@ -14,6 +14,8 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
...
@@ -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
start_slave
(
THD
*
thd
=
0
,
bool
net_report
=
1
);
int
stop_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
);
int
change_master
(
THD
*
thd
);
void
reset_slave
();
void
reset_slave
();
void
reset_master
();
void
reset_master
();
...
...
sql/sql_yacc.yy
View file @
8f6b34f9
...
@@ -2401,6 +2401,11 @@ load: LOAD DATA_SYM opt_low_priority opt_local INFILE TEXT_STRING
...
@@ -2401,6 +2401,11 @@ load: LOAD DATA_SYM opt_low_priority opt_local INFILE TEXT_STRING
YYABORT;
YYABORT;
}
}
|
LOAD DATA_SYM FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
}
opt_local:
opt_local:
/* empty */ { $$=0;}
/* 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