Here comes a nasty patch, although I am not ready to push it yet. I will

first pull, merge,test, and get it to work.

The main change is the new replication code - now we have two slave threads
SQL thread and I/O thread. I have also re-written a lot of the code to 
prepare for multi-master implementation. 

I also documented IO_CACHE quite extensively and to some extend, THD class.
parent f4812729
......@@ -446,3 +446,9 @@ vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
sql-bench/test-transactions
mysql-test/r/rpl000002.eval
mysql-test/r/rpl000014.eval
mysql-test/r/rpl000015.eval
mysql-test/r/rpl000016.eval
mysql-test/r/slave-running.eval
mysql-test/r/slave-stopped.eval
......@@ -74,14 +74,11 @@ bin-dist: all
$(top_builddir)/scripts/make_binary_distribution
tags:
rm -f TAGS
find -not -path \*SCCS\* -and \
\( -name \*.cc -or -name \*.h -or -name \*.yy -or -name \*.c \) \
-print -exec etags -o TAGS --append {} \;
support-files/build-tags
.PHONY: init-db bin-dist
# Test installation
test:
cd mysql-test ; ./mysql-test-run
......@@ -296,35 +296,105 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
typedef struct st_io_cache /* Used when cacheing files */
{
/* pos_in_file is offset in file corresponding to the first byte of
byte* buffer. end_of_file is the offset of end of file for READ_CACHE
and WRITE_CACHE. For SEQ_READ_APPEND it the maximum of the actual
end of file and the position represented by read_end.
*/
my_off_t pos_in_file,end_of_file;
/* read_pos points to current read position in the buffer
read_end is the non-inclusive boundary in the buffer for the currently
valid read area
buffer is the read buffer
not sure about request_pos except that it is used in async_io
*/
byte *read_pos,*read_end,*buffer,*request_pos;
/* write_buffer is used only in WRITE caches and in SEQ_READ_APPEND to
buffer writes
append_read_pos is only used in SEQ_READ_APPEND, and points to the
current read position in the write buffer. Note that reads in
SEQ_READ_APPEND caches can happen from both read buffer (byte* buffer),
and write buffer (byte* write_buffer).
write_pos points to current write position in the write buffer and
write_end is the non-inclusive boundary of the valid write area
*/
byte *write_buffer, *append_read_pos, *write_pos, *write_end;
/* current_pos and current_end are convenience variables used by
my_b_tell() and other routines that need to know the current offset
current_pos points to &write_pos, and current_end to &write_end in a
WRITE_CACHE, and &read_pos and &read_end respectively otherwise
*/
byte **current_pos, **current_end;
/* The lock is for append buffer used in READ_APPEND cache */
/* The lock is for append buffer used in SEQ_READ_APPEND cache */
#ifdef THREAD
pthread_mutex_t append_buffer_lock;
/* need mutex copying from append buffer to read buffer */
#endif
/* a caller will use my_b_read() macro to read from the cache
if the data is already in cache, it will be simply copied with
memcpy() and internal variables will be accordinging updated with
no functions invoked. However, if the data is not fully in the cache,
my_b_read() will call read_function to fetch the data. read_function
must never be invoked directly
*/
int (*read_function)(struct st_io_cache *,byte *,uint);
/* same idea as in the case of read_function, except my_b_write() needs to
be replaced with my_b_append() for a SEQ_READ_APPEND cache
*/
int (*write_function)(struct st_io_cache *,const byte *,uint);
/* specifies the type of the cache. Depending on the type of the cache
certain operations might not be available and yield unpredicatable
results. Details to be documented later
*/
enum cache_type type;
/* callbacks when the actual read I/O happens */
/* callbacks when the actual read I/O happens. These were added and
are currently used for binary logging of LOAD DATA INFILE - when a
block is read from the file, we create a block create/append event, and
when IO_CACHE is closed, we create an end event. These functions could,
of course be used for other things
*/
IO_CACHE_CALLBACK pre_read;
IO_CACHE_CALLBACK post_read;
IO_CACHE_CALLBACK pre_close;
void* arg; /* for use by pre/post_read */
char *file_name; /* if used with 'open_cached_file' */
char *dir,*prefix;
File file;
File file; /* file descriptor */
/* seek_not_done is set by my_b_seek() to inform the upcoming read/write
operation that a seek needs to be preformed prior to the actual I/O
error is 0 if the cache operation was successful, -1 if there was a
"hard" error, and the actual number of I/O-ed bytes if the read/write was
partial
*/
int seek_not_done,error;
/* buffer_length is the size of memory allocated for buffer or write_buffer
read_length is the same as buffer_length except when we use async io
not sure why we need it
*/
uint buffer_length,read_length;
myf myflags; /* Flags used to my_read/my_write */
/*
alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
0 if it was supplied by the user
Currently READ_NET is the only one that will use a buffer allocated
somewhere else
*/
my_bool alloced_buffer;
/* init_count is incremented every time we call init_io_cache()
It is not reset in end_io_cache(). This variable
was introduced for slave relay logs - RELAY_LOG_INFO stores a pointer
to IO_CACHE that could in some cases refer to the IO_CACHE of the
currently active relay log. The IO_CACHE then could be closed,
re-opened and start pointing to a different log file. In that case,
we could not know reliably if this happened without init_count
one must be careful with bzero() prior to the subsequent init_io_cache()
call
*/
int init_count;
#ifdef HAVE_AIOWAIT
/* as inidicated by ifdef, this is for async I/O, we will have
Sinisa comment this some time
*/
uint inited;
my_off_t aio_read_pos;
my_aio_result aio_result;
......@@ -369,6 +439,8 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_tell(info) ((info)->pos_in_file + \
(uint) (*(info)->current_pos - (info)->request_pos))
#define my_b_append_tell(info) ((info)->end_of_file + \
(uint) ((info)->write_pos - (info)->write_buffer))
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
*(info)->current_pos)
......
......@@ -396,8 +396,8 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_binlog_update, MY_MUTEX_INIT_FAST); // QQ NOT USED
(void) pthread_mutex_init(&LOCK_slave, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_slave_io, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_slave_sql, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_cond_init(&COND_thread_count,NULL);
......@@ -406,8 +406,11 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
(void) pthread_cond_init(&COND_binlog_update, NULL);
(void) pthread_cond_init(&COND_slave_stopped, NULL);
(void) pthread_cond_init(&COND_slave_start, NULL);
(void) pthread_cond_init(&COND_slave_log_update, NULL);
(void) pthread_cond_init(&COND_slave_sql_stop, NULL);
(void) pthread_cond_init(&COND_slave_sql_start, NULL);
(void) pthread_cond_init(&COND_slave_sql_stop, NULL);
(void) pthread_cond_init(&COND_slave_sql_start, NULL);
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
{
......
......@@ -7,22 +7,22 @@ show master status;
File Position Binlog_do_db Binlog_ignore_db
master-bin.001 79
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.001 79 Yes 0 0 1
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 1 master-bin.001 79 mysql-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79
change master to master_log_pos=73;
slave stop;
change master to master_log_pos=73;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.001 73 No 0 0 1
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 1 master-bin.001 73 mysql-relay-bin.001 4 master-bin.001 No No 0 0 73
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.001 73 Yes 0 0 1
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 1 master-bin.001 73 mysql-relay-bin.001 4 master-bin.001 Yes Yes 0 0 73
change master to master_log_pos=173;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.001 173 Yes 0 0 1
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 1 master-bin.001 173 mysql-relay-bin.001 4 master-bin.001 Yes Yes 0 0 173
show master status;
File Position Binlog_do_db Binlog_ignore_db
master-bin.001 79
......
......@@ -4,21 +4,21 @@ File Position Binlog_do_db Binlog_ignore_db
master-bin.001 79
reset slave;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
0 0 0 No 0 0 0
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
0 0 0 0 No No 0 0 0
change master to master_host='127.0.0.1';
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 test 3306 60 4 No 0 0 0
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 test 3306 60 4 mysql-relay-bin.001 4 No No 0 0 0
change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=9306;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root 9306 60 4 No 0 0 0
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 60 4 mysql-relay-bin.001 4 No No 0 0 0
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root 9306 60 master-bin.001 79 Yes 0 0 1
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 60 master-bin.001 79 mysql-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79
drop table if exists t1;
create table t1 (n int);
insert into t1 values (10),(45),(90);
......
......@@ -14,8 +14,8 @@ drop table if exists t1;
create table t1 (s text);
insert into t1 values('Could not break slave'),('Tried hard');
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root 9306 60 master-bin.001 234 Yes 0 0 3
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 60 master-bin.001 234 mysql-relay-bin.001 275 master-bin.001 Yes Yes 0 0 234
select * from t1;
s
Could not break slave
......@@ -42,8 +42,8 @@ Log_name
master-bin.003
insert into t2 values (65);
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root 9306 60 master-bin.003 155 Yes 0 0 3
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 60 master-bin.003 155 mysql-relay-bin.001 793 master-bin.003 Yes Yes 0 0 155
select * from t2;
m
34
......@@ -65,8 +65,8 @@ master-bin.006 445
slave stop;
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root 9306 60 master-bin.006 445 Yes 0 0 7
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 60 master-bin.006 445 mysql-relay-bin.004 1376 master-bin.006 Yes Yes 0 0 445
lock tables t3 read;
select count(*) from t3 where n >= 4;
count(*)
......
......@@ -15,48 +15,48 @@ create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
drop table t1;
show binlog events;
Log_name Pos Event_type Server_id Log_seq Info
master-bin.001 4 Start 1 1 Server ver: $VERSION, Binlog ver: 2
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 3 INSERT_ID=1
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 5 use test; drop table t1
master-bin.001 311 Query 1 6 use test; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 7 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 8 ;file_id=1
master-bin.001 579 Query 1 9 use test; drop table t1
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 4 Start 1 4 Server ver: 4.0.1-alpha-debug-log, Binlog ver: 3
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use test; drop table t1
master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 556 ;file_id=1
master-bin.001 579 Query 1 579 use test; drop table t1
show binlog events from 79 limit 1;
Log_name Pos Event_type Server_id Log_seq Info
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
show binlog events from 79 limit 2;
Log_name Pos Event_type Server_id Log_seq Info
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 3 INSERT_ID=1
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
show binlog events from 79 limit 2,1;
Log_name Pos Event_type Server_id Log_seq Info
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
flush logs;
create table t1 (n int);
insert into t1 values (1);
drop table t1;
show binlog events;
Log_name Pos Event_type Server_id Log_seq Info
master-bin.001 4 Start 1 1 Server ver: $VERSION, Binlog ver: 2
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 3 INSERT_ID=1
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 5 use test; drop table t1
master-bin.001 311 Query 1 6 use test; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 7 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 8 ;file_id=1
master-bin.001 579 Query 1 9 use test; drop table t1
master-bin.001 627 Rotate 1 10 master-bin.002;pos=4
master-bin.001 668 Stop 1 11
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.001 4 Start 1 4 Server ver: 4.0.1-alpha-debug-log, Binlog ver: 3
master-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
master-bin.001 172 Intvar 1 172 INSERT_ID=1
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
master-bin.001 263 Query 1 263 use test; drop table t1
master-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null)
master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
master-bin.001 556 Exec_load 1 556 ;file_id=1
master-bin.001 579 Query 1 579 use test; drop table t1
master-bin.001 627 Rotate 1 627 master-bin.002;pos=4
master-bin.001 668 Stop 1 668
show binlog events in 'master-bin.002';
Log_name Pos Event_type Server_id Log_seq Info
master-bin.002 4 Query 1 1 use test; create table t1 (n int)
master-bin.002 62 Query 1 2 use test; insert into t1 values (1)
master-bin.002 122 Query 1 3 use test; drop table t1
Log_name Pos Event_type Server_id Orig_log_pos Info
master-bin.002 4 Query 1 4 use test; create table t1 (n int)
master-bin.002 62 Query 1 62 use test; insert into t1 values (1)
master-bin.002 122 Query 1 122 use test; drop table t1
show master logs;
Log_name
master-bin.001
......@@ -67,45 +67,45 @@ Log_name
slave-bin.001
slave-bin.002
show binlog events in 'slave-bin.001' from 4;
Log_name Pos Event_type Server_id Log_seq Info
slave-bin.001 4 Start 2 1 Server ver: $VERSION, Binlog ver: 2
slave-bin.001 79 Slave 2 3 host=127.0.0.1,port=$MASTER_MYPORT,log=master-bin.001,pos=4
slave-bin.001 132 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
slave-bin.001 225 Intvar 1 3 INSERT_ID=1
slave-bin.001 253 Query 1 4 use test; insert into t1 values (NULL)
slave-bin.001 316 Query 1 5 use test; drop table t1
slave-bin.001 364 Query 1 6 use test; create table t1 (word char(20) not null)
slave-bin.001 439 Create_file 1 7 db=test;table=t1;file_id=1;block_len=81
slave-bin.001 618 Exec_load 1 8 ;file_id=1
slave-bin.001 641 Query 1 9 use test; drop table t1
slave-bin.001 689 Rotate 1 4 slave-bin.002;pos=4; forced by master
slave-bin.001 729 Stop 2 5
Log_name Pos Event_type Server_id Orig_log_pos Info
slave-bin.001 4 Start 2 4 Server ver: 4.0.1-alpha-debug-log, Binlog ver: 3
slave-bin.001 79 Slave 2 79 host=127.0.0.1,port=9306,log=master-bin.001,pos=4
slave-bin.001 132 Query 1 79 use test; create table t1(n int not null auto_increment primary key)
slave-bin.001 225 Intvar 1 200 INSERT_ID=1
slave-bin.001 253 Query 1 200 use test; insert into t1 values (NULL)
slave-bin.001 316 Query 1 263 use test; drop table t1
slave-bin.001 364 Query 1 311 use test; create table t1 (word char(20) not null)
slave-bin.001 439 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
slave-bin.001 618 Exec_load 1 556 ;file_id=1
slave-bin.001 641 Query 1 579 use test; drop table t1
slave-bin.001 689 Rotate 1 627 slave-bin.002;pos=4; forced by master
slave-bin.001 729 Stop 2 729
show binlog events in 'slave-bin.002' from 4;
Log_name Pos Event_type Server_id Log_seq Info
slave-bin.002 4 Slave 2 10 host=127.0.0.1,port=$MASTER_MYPORT,log=master-bin.002,pos=4
slave-bin.002 57 Query 1 1 use test; create table t1 (n int)
slave-bin.002 115 Query 1 2 use test; insert into t1 values (1)
slave-bin.002 175 Query 1 3 use test; drop table t1
Log_name Pos Event_type Server_id Orig_log_pos Info
slave-bin.002 4 Slave 2 627 host=127.0.0.1,port=9306,log=master-bin.002,pos=4
slave-bin.002 57 Query 1 4 use test; create table t1 (n int)
slave-bin.002 115 Query 1 62 use test; insert into t1 values (1)
slave-bin.002 175 Query 1 122 use test; drop table t1
show slave status;
Master_Host Master_User Master_Port Connect_retry Log_File Pos Slave_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Last_log_seq
127.0.0.1 root $MASTER_MYPORT 1 master-bin.002 170 Yes 0 0 3
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
127.0.0.1 root 9306 1 master-bin.002 170 mysql-relay-bin.002 935 master-bin.002 Yes Yes 0 0 170
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=4 and master_log_seq=1 and master_server_id=1;
master_log_pos=4 and master_server_id=1;
Log_name Log_pos
slave-bin.001 132
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=79 and master_log_seq=2 and master_server_id=1;
master_log_pos=79 and master_server_id=1;
Log_name Log_pos
slave-bin.001 225
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=311 and master_log_seq=6 and master_server_id=1;
master_log_pos=311 and master_server_id=1;
Log_name Log_pos
slave-bin.001 439
show new master for slave with master_log_file='master-bin.002' and
master_log_pos=4 and master_log_seq=1 and master_server_id=1;
master_log_pos=4 and master_server_id=1;
Log_name Log_pos
slave-bin.002 57
show new master for slave with master_log_file='master-bin.002' and
master_log_pos=137 and master_log_seq=3 and master_server_id=1;
master_log_pos=122 and master_server_id=1;
Log_name Log_pos
slave-bin.002 223
#! /bin/sh
# A shortcut for resolving stacks when debugging when
# we cannot duplicate the crash in a debugger and have to
# resort to using stack traces
nm --numeric-sort ../sql/mysqld > var/tmp/mysqld.sym
echo "Please type or paste the numeric stack trace,Ctrl-C to quit:"
../extra/resolve_stack_dump -s var/tmp/mysqld.sym
-O max_binlog_size=2048
rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF
master-bin.001
4
......
......@@ -37,13 +37,13 @@ show binlog events in 'slave-bin.001' from 4;
show binlog events in 'slave-bin.002' from 4;
show slave status;
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=4 and master_log_seq=1 and master_server_id=1;
master_log_pos=4 and master_server_id=1;
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=79 and master_log_seq=2 and master_server_id=1;
master_log_pos=79 and master_server_id=1;
show new master for slave with master_log_file='master-bin.001' and
master_log_pos=311 and master_log_seq=6 and master_server_id=1;
master_log_pos=311 and master_server_id=1;
show new master for slave with master_log_file='master-bin.002' and
master_log_pos=4 and master_log_seq=1 and master_server_id=1;
master_log_pos=4 and master_server_id=1;
show new master for slave with master_log_file='master-bin.002' and
master_log_pos=137 and master_log_seq=3 and master_server_id=1;
master_log_pos=122 and master_server_id=1;
......@@ -123,6 +123,8 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
info->pos_in_file= seek_offset;
info->pre_close = info->pre_read = info->post_read = 0;
info->arg = 0;
info->init_count++; /* we assume the user had set it to 0 prior to
first call */
info->alloced_buffer = 0;
info->buffer=0;
info->seek_not_done= test(file >= 0);
......@@ -447,11 +449,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
info->end_of_file)
goto read_append_buffer;
if (info->seek_not_done)
{ /* File touched, do seek */
/*
With read-append cache we must always do a seek before we read,
because the write could have moved the file pointer astray
*/
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
info->seek_not_done=0;
}
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
/* now the second stage begins - read from file descriptor */
......@@ -507,6 +511,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
memcpy(Buffer,info->buffer,(size_t) length);
Count -= length;
Buffer += length;
/*
added the line below to make
DBUG_ASSERT(pos_in_file==info->end_of_file) pass.
otherwise this does not appear to be needed
*/
pos_in_file += length;
goto read_append_buffer;
}
}
......@@ -528,10 +539,13 @@ read_append_buffer:
/* First copy the data to Count */
uint len_in_buff = (uint) (info->write_pos - info->append_read_pos);
uint copy_len;
uint transfer_len;
DBUG_ASSERT(info->append_read_pos <= info->write_pos);
/*
TODO: figure out if the below assert is needed or correct.
*/
DBUG_ASSERT(pos_in_file == info->end_of_file);
copy_len=min(Count, len_in_buff);
memcpy(Buffer, info->append_read_pos, copy_len);
info->append_read_pos += copy_len;
......@@ -541,11 +555,12 @@ read_append_buffer:
/* Fill read buffer with data from write buffer */
memcpy(info->buffer, info->append_read_pos,
(size_t) (len_in_buff - copy_len));
(size_t) (transfer_len=len_in_buff - copy_len));
info->read_pos= info->buffer;
info->read_end= info->buffer+(len_in_buff - copy_len);
info->read_end= info->buffer+transfer_len;
info->append_read_pos=info->write_pos;
info->pos_in_file+=len_in_buff;
info->pos_in_file=pos_in_file+copy_len;
info->end_of_file+=len_in_buff;
}
unlock_append_buffer(info);
return Count ? 1 : 0;
......@@ -887,12 +902,10 @@ int flush_io_cache(IO_CACHE *info)
if ((length=(uint) (info->write_pos - info->write_buffer)))
{
pos_in_file=info->pos_in_file;
if (append_cache)
{
pos_in_file=info->end_of_file;
info->seek_not_done=1;
}
if (info->seek_not_done)
/* if we have append cache, we always open the file with
O_APPEND which moves the pos to EOF automatically on every write
*/
if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
......@@ -902,20 +915,24 @@ int flush_io_cache(IO_CACHE *info)
if (!append_cache)
info->seek_not_done=0;
}
info->write_pos= info->write_buffer;
if (!append_cache)
info->pos_in_file+=length;
info->write_end= (info->write_buffer+info->buffer_length-
((pos_in_file+length) & (IO_SIZE-1)));
/* Set this to be used if we are using SEQ_READ_APPEND */
info->append_read_pos = info->write_buffer;
if (my_write(info->file,info->write_buffer,length,
info->myflags | MY_NABP))
info->error= -1;
else
info->error= 0;
if (!append_cache)
{
set_if_bigger(info->end_of_file,(pos_in_file+length));
}
else
info->end_of_file+=(info->write_pos-info->append_read_pos);
info->append_read_pos=info->write_pos=info->write_buffer;
DBUG_RETURN(info->error);
}
}
......
......@@ -32,12 +32,26 @@
void my_b_seek(IO_CACHE *info,my_off_t pos)
{
my_off_t offset = (pos - info->pos_in_file);
my_off_t offset;
DBUG_ENTER("my_b_seek");
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
if (info->type == READ_CACHE)
/*
TODO: verify that it is OK to do seek in the non-append
area in SEQ_READ_APPEND cache
*/
/* TODO:
a) see if this always works
b) see if there is a better way to make it work
*/
if (info->type == SEQ_READ_APPEND)
flush_io_cache(info);
offset=(pos - info->pos_in_file);
if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
{
/* TODO: explain why this works if pos < info->pos_in_file */
if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
{
/* The read is in the current buffer; Reuse it */
......
......@@ -70,7 +70,8 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
}
if (mp->count++)
{
fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, \
line %d more than 1 time\n", file,line);
fflush(stderr);
abort();
}
......
......@@ -1453,11 +1453,13 @@ longlong Item_master_pos_wait::val_int()
return 0;
}
ulong pos = (ulong)args[1]->val_int();
if ((event_count = glob_mi.wait_for_pos(thd, log_name, pos)) == -1)
LOCK_ACTIVE_MI;
if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos)) == -1)
{
null_value = 1;
event_count=0;
}
UNLOCK_ACTIVE_MI;
return event_count;
}
......
......@@ -218,7 +218,6 @@ static SYMBOL symbols[] = {
{ "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0},
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM),0,0},
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM),0,0},
{ "MASTER_LOG_SEQ", SYM(MASTER_LOG_SEQ_SYM),0,0},
{ "MASTER_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
{ "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
......
This diff is collapsed.
This diff is collapsed.
......@@ -34,7 +34,7 @@
#define LOG_READ_TOO_LARGE -7
#define LOG_EVENT_OFFSET 4
#define BINLOG_VERSION 2
#define BINLOG_VERSION 3
/* we could have used SERVER_VERSION_LENGTH, but this introduces an
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
......@@ -120,7 +120,7 @@ struct sql_ex_info
#define EVENT_TYPE_OFFSET 4
#define SERVER_ID_OFFSET 5
#define EVENT_LEN_OFFSET 9
#define LOG_SEQ_OFFSET 13
#define LOG_POS_OFFSET 13
#define FLAGS_OFFSET 17
/* start event post-header */
......@@ -206,7 +206,7 @@ class THD;
extern uint32 server_id;
struct st_master_info;
struct st_relay_log_info;
class Log_event
{
......@@ -214,7 +214,7 @@ public:
time_t when;
ulong exec_time;
uint32 server_id;
uint32 log_seq;
uint32 log_pos;
uint16 flags;
int cached_event_len;
char* temp_buf;
......@@ -282,11 +282,11 @@ public:
#ifndef MYSQL_CLIENT
static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock);
void set_log_seq(THD* thd, MYSQL_LOG* log);
void set_log_pos(MYSQL_LOG* log);
virtual void pack_info(String* packet);
int net_send(THD* thd, const char* log_name, my_off_t pos);
static void init_show_field_list(List<Item>* field_list);
virtual int exec_event(struct st_master_info* mi);
virtual int exec_event(struct st_relay_log_info* rli);
virtual const char* get_db()
{
return thd ? thd->db : 0;
......@@ -316,7 +316,7 @@ public:
bool using_trans=0);
const char* get_db() { return db; }
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
bool get_cache_stmt() { return cache_stmt; }
#endif
......@@ -359,9 +359,9 @@ public:
ulonglong master_pos;
#ifndef MYSQL_CLIENT
Slave_log_event(THD* thd_arg, struct st_master_info* mi);
Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
Slave_log_event(const char* buf, int event_len);
......@@ -407,11 +407,11 @@ public:
void set_fields(List<Item> &fields_arg);
void pack_info(String* packet);
const char* get_db() { return db; }
int exec_event(struct st_master_info* mi)
int exec_event(struct st_relay_log_info* rli)
{
return exec_event(thd->slave_net,mi);
return exec_event(thd->slave_net,rli);
}
int exec_event(NET* net, struct st_master_info* mi);
int exec_event(NET* net, struct st_relay_log_info* rli);
#endif
Load_log_event(const char* buf, int event_len, bool old_format);
......@@ -465,7 +465,7 @@ public:
}
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
#ifdef MYSQL_CLIENT
void print(FILE* file, bool short_form = 0, char* last_db = 0);
......@@ -491,7 +491,7 @@ public:
bool is_valid() { return 1; }
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
#ifdef MYSQL_CLIENT
......@@ -517,7 +517,7 @@ public:
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
#ifndef MYSQL_CLIENT
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
};
......@@ -553,7 +553,7 @@ public:
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
};
......@@ -602,7 +602,7 @@ public:
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
};
......@@ -616,7 +616,7 @@ public:
#ifndef MYSQL_CLIENT
Append_block_log_event(THD* thd, char* block_arg,
uint block_len_arg);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
Append_block_log_event(const char* buf, int event_len);
......@@ -659,7 +659,7 @@ public:
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
};
......@@ -686,7 +686,7 @@ public:
#endif
#ifndef MYSQL_CLIENT
void pack_info(String* packet);
int exec_event(struct st_master_info* mi);
int exec_event(struct st_relay_log_info* rli);
#endif
};
......
......@@ -101,7 +101,7 @@ 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);
void mc_end_server(MYSQL *mysql);
static int mc_sock_connect(File s, const struct sockaddr *name, uint namelen, uint to);
static void mc_free_old_query(MYSQL *mysql);
static int mc_send_file_to_server(MYSQL *mysql, const char *filename);
......@@ -206,8 +206,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
** Init MySQL structure or allocate one
****************************************************************************/
MYSQL * STDCALL
mc_mysql_init(MYSQL *mysql)
MYSQL *mc_mysql_init(MYSQL *mysql)
{
init_client_errs();
if (!mysql)
......@@ -229,7 +228,7 @@ mc_mysql_init(MYSQL *mysql)
** Shut down connection
**************************************************************************/
static void
void
mc_end_server(MYSQL *mysql)
{
DBUG_ENTER("mc_end_server");
......@@ -351,7 +350,7 @@ static int mc_sock_connect(my_socket s, const struct sockaddr *name,
** or packet is an error message
*****************************************************************************/
ulong STDCALL
ulong
mc_net_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
......@@ -412,17 +411,17 @@ max_allowed_packet on this server");
}
char * STDCALL mc_mysql_error(MYSQL *mysql)
char * mc_mysql_error(MYSQL *mysql)
{
return (mysql)->net.last_error;
}
int STDCALL mc_mysql_errno(MYSQL *mysql)
int mc_mysql_errno(MYSQL *mysql)
{
return (mysql)->net.last_errno;
}
my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
my_bool mc_mysql_reconnect(MYSQL *mysql)
{
MYSQL tmp_mysql;
DBUG_ENTER("mc_mysql_reconnect");
......@@ -452,7 +451,7 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
int STDCALL
int
mc_simple_command(MYSQL *mysql,enum enum_server_command command,
const char *arg, uint length, my_bool skipp_check)
{
......@@ -505,7 +504,7 @@ mc_simple_command(MYSQL *mysql,enum enum_server_command command,
}
MYSQL * STDCALL
MYSQL *
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
......@@ -856,7 +855,7 @@ error:
** NB! Errors are not reported until you do mysql_real_connect.
**************************************************************************
*/
int STDCALL
int
mysql_ssl_clear(MYSQL *mysql)
{
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
......@@ -879,7 +878,7 @@ mysql_ssl_clear(MYSQL *mysql)
** If handle is alloced by mysql connect free it.
*************************************************************************/
void STDCALL
void
mc_mysql_close(MYSQL *mysql)
{
DBUG_ENTER("mysql_close");
......@@ -910,7 +909,7 @@ mc_mysql_close(MYSQL *mysql)
DBUG_VOID_RETURN;
}
void STDCALL mc_mysql_free_result(MYSQL_RES *result)
void mc_mysql_free_result(MYSQL_RES *result)
{
DBUG_ENTER("mc_mysql_free_result");
DBUG_PRINT("enter",("mysql_res: %lx",result));
......@@ -988,13 +987,13 @@ mc_unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
DBUG_RETURN(result);
}
int STDCALL
int
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)
int mc_mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
......@@ -1042,7 +1041,7 @@ get_info:
DBUG_RETURN(0);
}
int STDCALL mc_mysql_query(MYSQL *mysql, const char *query, uint length)
int mc_mysql_query(MYSQL *mysql, const char *query, uint length)
{
DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
......@@ -1289,17 +1288,17 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
return 0;
}
my_ulonglong STDCALL mc_mysql_num_rows(MYSQL_RES *res)
my_ulonglong mc_mysql_num_rows(MYSQL_RES *res)
{
return res->row_count;
}
unsigned int STDCALL mc_mysql_num_fields(MYSQL_RES *res)
unsigned int mc_mysql_num_fields(MYSQL_RES *res)
{
return res->field_count;
}
void STDCALL mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
{
MYSQL_ROWS *tmp=0;
DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
......@@ -1309,7 +1308,7 @@ void STDCALL mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
result->data_cursor = tmp;
}
MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res)
MYSQL_ROW mc_mysql_fetch_row(MYSQL_RES *res)
{
DBUG_ENTER("mc_mysql_fetch_row");
if (!res->data)
......@@ -1344,7 +1343,7 @@ MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res)
}
}
int STDCALL mc_mysql_select_db(MYSQL *mysql, const char *db)
int mc_mysql_select_db(MYSQL *mysql, const char *db)
{
int error;
DBUG_ENTER("mysql_select_db");
......@@ -1358,7 +1357,7 @@ int STDCALL mc_mysql_select_db(MYSQL *mysql, const char *db)
}
MYSQL_RES * STDCALL mc_mysql_store_result(MYSQL *mysql)
MYSQL_RES *mc_mysql_store_result(MYSQL *mysql)
{
MYSQL_RES *result;
DBUG_ENTER("mysql_store_result");
......
......@@ -18,41 +18,35 @@
#define _MINI_CLIENT_H
MYSQL* STDCALL
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
MYSQL* mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag);
int STDCALL
mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
int mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
uint length, my_bool skipp_check);
void STDCALL
mc_mysql_close(MYSQL *mysql);
MYSQL * STDCALL
mc_mysql_init(MYSQL *mysql);
void STDCALL
mc_mysql_debug(const char *debug);
ulong STDCALL
mc_net_safe_read(MYSQL *mysql);
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);
void mc_mysql_close(MYSQL *mysql);
MYSQL * mc_mysql_init(MYSQL *mysql);
void mc_mysql_debug(const char *debug);
ulong mc_net_safe_read(MYSQL *mysql);
char * mc_mysql_error(MYSQL *mysql);
int mc_mysql_errno(MYSQL *mysql);
my_bool mc_mysql_reconnect(MYSQL* mysql);
int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
int mc_mysql_read_query_result(MYSQL *mysql);
int mc_mysql_query(MYSQL *mysql, const char *query, uint length);
MYSQL_RES * mc_mysql_store_result(MYSQL *mysql);
void mc_mysql_free_result(MYSQL_RES *result);
void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row);
my_ulonglong mc_mysql_num_rows(MYSQL_RES *res);
unsigned int mc_mysql_num_fields(MYSQL_RES *res);
MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res);
int mc_mysql_select_db(MYSQL *mysql, const char *db);
void mc_end_server(MYSQL *mysql);
#endif
......@@ -519,6 +519,10 @@ void sql_print_error(const char *format,...)
__attribute__ ((format (printf, 1, 2)));
bool fn_format_relative_to_data_home(my_string to, const char *name,
const char *dir, const char *extension);
void open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
enum_log_type type, bool read_append = 0,
bool no_auto_events = 0);
extern uint32 server_id;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
......@@ -550,9 +554,8 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_binlog_update, LOCK_slave, LOCK_server_id, LOCK_slave_list;
extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
COND_slave_stopped, COND_slave_start;
LOCK_server_id, LOCK_slave_list, LOCK_active_mi;
extern pthread_cond_t COND_refresh,COND_thread_count;
extern pthread_attr_t connection_attrib;
extern bool opt_endinfo, using_udf_functions, locked_in_memory,
opt_using_transactions, use_temp_pool, mysql_embedded;
......@@ -588,6 +591,7 @@ extern struct show_var_st init_vars[];
extern struct show_var_st status_vars[];
extern enum db_type default_table_type;
extern enum enum_tx_isolation default_tx_isolation;
extern char glob_hostname[FN_REFLEN];
#ifndef __WIN__
extern pthread_t signal_thread;
......
......@@ -206,7 +206,7 @@ SHOW_COMP_OPTION have_openssl=SHOW_OPTION_NO;
SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES;
static bool opt_skip_slave_start = 0; // If set, slave is not autostarted
bool opt_skip_slave_start = 0; // If set, slave is not autostarted
static bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH;
static ulong back_log,connect_timeout,concurrency;
......@@ -225,8 +225,6 @@ bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0,
opt_safe_user_create = 0, opt_no_mix_types = 0;
FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi);
/*
If sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
......@@ -238,7 +236,7 @@ static struct rand_struct sql_rand;
static int cleanup_done;
static char **defaults_argv,time_zone[30];
static const char *default_table_type_name;
static char glob_hostname[FN_REFLEN];
char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
......@@ -274,7 +272,9 @@ volatile ulong cached_thread_count=0;
// replication parameters, if master_host is not NULL, we are a slave
my_string master_user = (char*) "test", master_password = 0, master_host=0,
master_info_file = (char*) "master.info", master_ssl_key=0, master_ssl_cert=0;
master_info_file = (char*) "master.info",
relay_log_info_file = (char*) "relay-log.info",
master_ssl_key=0, master_ssl_cert=0;
my_string report_user = 0, report_password = 0, report_host=0;
const char *localhost=LOCAL_HOST;
......@@ -321,6 +321,7 @@ bool mysql_embedded=1;
#endif
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
const char **errmesg; /* Error messages */
......@@ -356,11 +357,10 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_binlog_update, LOCK_slave, LOCK_server_id,
LOCK_user_conn, LOCK_slave_list;
LOCK_server_id,
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
COND_slave_stopped, COND_slave_start;
pthread_cond_t COND_refresh,COND_thread_count;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
......@@ -759,6 +759,7 @@ void clean_up(bool print_message)
my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
x_free(opt_bin_logname);
x_free(opt_relay_logname);
bitmap_free(&temp_pool);
free_max_user_conn();
end_slave_list();
......@@ -1095,6 +1096,8 @@ void end_thread(THD *thd, bool put_in_cache)
DBUG_PRINT("info", ("sending a broadcast"))
/* Tell main we are ready */
// TODO: explain why we broadcast outside of the lock or
// fix the bug - Sasha
(void) pthread_mutex_unlock(&LOCK_thread_count);
(void) pthread_cond_broadcast(&COND_thread_count);
DBUG_PRINT("info", ("unlocked thread_count mutex"))
......@@ -1266,6 +1269,7 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
#ifdef HAVE_STACKTRACE
if(!(test_flags & TEST_NO_STACKTRACE))
{
fprintf(stderr,"thd=%p\n",thd);
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);
}
......@@ -1594,9 +1598,10 @@ const char *load_default_groups[]= { "mysqld","server",0 };
char *libwrapName=NULL;
#endif
static void open_log(MYSQL_LOG *log, const char *hostname,
void open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
enum_log_type type)
enum_log_type type, bool read_append,
bool no_auto_events)
{
char tmp[FN_REFLEN];
if (!opt_name || !opt_name[0])
......@@ -1620,7 +1625,8 @@ static void open_log(MYSQL_LOG *log, const char *hostname,
opt_name=tmp;
}
}
log->open(opt_name,type);
log->open(opt_name,type,0,(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
no_auto_events);
}
......@@ -1716,19 +1722,15 @@ int main(int argc, char **argv)
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_binlog_update, MY_MUTEX_INIT_FAST); // QQ NOT USED
(void) pthread_mutex_init(&LOCK_slave, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_server_id, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
(void) pthread_cond_init(&COND_binlog_update, NULL);
(void) pthread_cond_init(&COND_slave_stopped, NULL);
(void) pthread_cond_init(&COND_slave_start, NULL);
(void) pthread_cond_init(&COND_rpl_status, NULL);
init_signals();
......@@ -1826,18 +1828,7 @@ int main(int argc, char **argv)
using_update_log=1;
}
/*
make sure slave thread gets started if server_id is set,
valid master.info is present, and master_host has not been specified
*/
if (server_id && !master_host)
{
char fname[FN_REFLEN+128];
MY_STAT stat_area;
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
if (my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi))
master_host = glob_mi.host;
}
init_slave();
if (opt_bin_log && !server_id)
{
......@@ -1991,17 +1982,6 @@ The server will not act as a slave.");
sql_print_error("Warning: Can't create thread to manage maintenance");
}
// slave thread
if (master_host)
{
pthread_t hThread;
if (!opt_skip_slave_start &&
pthread_create(&hThread, &connection_attrib, handle_slave, 0))
sql_print_error("Warning: Can't create thread to handle slave");
else if(opt_skip_slave_start)
init_master_info(&glob_mi);
}
printf(ER(ER_READY),my_progname,server_version,"");
fflush(stdout);
......@@ -2665,7 +2645,8 @@ enum options {
OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE
OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE
};
static struct option long_options[] = {
......@@ -2790,6 +2771,8 @@ static struct option long_options[] = {
{"report-password", required_argument, 0, (int) OPT_REPORT_PASSWORD},
{"report-port", required_argument, 0, (int) OPT_REPORT_PORT},
{"rpl-recovery-rank", required_argument, 0, (int) OPT_RPL_RECOVERY_RANK},
{"relay-log", required_argument, 0, (int) OPT_RELAY_LOG},
{"relay-log-index", required_argument, 0, (int) OPT_RELAY_LOG_INDEX},
{"safe-mode", no_argument, 0, (int) OPT_SAFE},
{"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
{"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE},
......@@ -2813,6 +2796,8 @@ static struct option long_options[] = {
{"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
{"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
{"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
{"relay-log-info-file", required_argument, 0,
(int) OPT_RELAY_LOG_INFO_FILE},
{"slave-load-tmpdir", required_argument, 0, (int) OPT_SLAVE_LOAD_TMPDIR},
{"socket", required_argument, 0, (int) OPT_SOCKET},
{"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME},
......@@ -3151,8 +3136,8 @@ struct show_var_st status_vars[]= {
{"Select_range", (char*) &select_range_count, SHOW_LONG},
{"Select_range_check", (char*) &select_range_check_count, SHOW_LONG},
{"Select_scan", (char*) &select_scan_count, SHOW_LONG},
{"Slave_running", (char*) &slave_running, SHOW_BOOL},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) &long_query_count, SHOW_LONG},
{"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG},
......@@ -3548,6 +3533,14 @@ static void get_options(int argc,char **argv)
opt_update_log=1;
opt_update_logname=optarg; // Use hostname.# if null
break;
case (int) OPT_RELAY_LOG_INDEX:
opt_relaylog_index_name = optarg;
break;
case (int) OPT_RELAY_LOG:
x_free(opt_relay_logname);
if (optarg && optarg[0])
opt_relay_logname=my_strdup(optarg,MYF(0));
break;
case (int) OPT_BIN_LOG_INDEX:
opt_binlog_index_name = optarg;
break;
......@@ -4007,6 +4000,9 @@ static void get_options(int argc,char **argv)
case OPT_MASTER_INFO_FILE:
master_info_file=optarg;
break;
case OPT_RELAY_LOG_INFO_FILE:
relay_log_info_file=optarg;
break;
case OPT_MASTER_PORT:
master_port= atoi(optarg);
break;
......
......@@ -199,7 +199,7 @@ void end_slave_list()
static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
{
uint32 log_seq = mi->last_log_seq;
uint32 log_pos = mi->pos;
uint32 target_server_id = mi->server_id;
for (;;)
......@@ -217,7 +217,7 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
return 1;
}
if (ev->log_seq == log_seq && ev->server_id == target_server_id)
if (ev->log_pos == log_pos && ev->server_id == target_server_id)
{
delete ev;
mi->pos = my_b_tell(log);
......@@ -527,7 +527,7 @@ pthread_handler_decl(handle_failsafe_rpl,arg)
const char* msg = thd->enter_cond(&COND_rpl_status,
&LOCK_rpl_status, "Waiting for request");
pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
thd->proc_info="Processling request";
thd->proc_info="Processing request";
while (!break_req_chain)
{
switch (rpl_status)
......@@ -630,10 +630,9 @@ static inline void cleanup_mysql_results(MYSQL_RES* db_res,
static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
MYSQL_RES* table_res)
MYSQL_RES* table_res, MASTER_INFO* mi)
{
MYSQL_ROW row;
for( row = mc_mysql_fetch_row(table_res); row;
row = mc_mysql_fetch_row(table_res))
{
......@@ -649,11 +648,9 @@ static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
if (!tables_ok(thd, &table))
continue;
}
if ((error = fetch_nx_table(thd, db, table_name, &glob_mi, mysql)))
if ((error = fetch_master_table(thd, db, table_name, mi, mysql)))
return error;
}
return 0;
}
......@@ -664,25 +661,26 @@ int load_master_data(THD* thd)
MYSQL_RES* master_status_res = 0;
bool slave_was_running = 0;
int error = 0;
const char* errmsg=0;
int restart_thread_mask;
mc_mysql_init(&mysql);
// we do not want anyone messing with the slave at all for the entire
// duration of the data load;
pthread_mutex_lock(&LOCK_slave);
// first, kill the slave
if ((slave_was_running = slave_running))
{
abort_slave = 1;
KICK_SLAVE;
thd->proc_info = "waiting for slave to die";
while (slave_running)
pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done
LOCK_ACTIVE_MI;
lock_slave_threads(active_mi);
init_thread_mask(&restart_thread_mask,active_mi,0 /*not inverse*/);
if (restart_thread_mask &&
(error=terminate_slave_threads(active_mi,restart_thread_mask,
1 /*skip lock*/)))
{
send_error(&thd->net,error);
unlock_slave_threads(active_mi);
UNLOCK_ACTIVE_MI;
return 1;
}
if (connect_to_master(thd, &mysql, &glob_mi))
if (connect_to_master(thd, &mysql, active_mi))
{
net_printf(&thd->net, error = ER_CONNECT_TO_MASTER,
mc_mysql_error(&mysql));
......@@ -744,7 +742,7 @@ int load_master_data(THD* thd)
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
TODO - add special option, not enabled
by default, to allow inclusion of mysql database into load
data from master
*/
......@@ -774,7 +772,7 @@ int load_master_data(THD* thd)
goto err;
}
if ((error = fetch_db_tables(thd, &mysql, db, *cur_table_res)))
if ((error = fetch_db_tables(thd,&mysql,db,*cur_table_res,active_mi)))
{
// we do not report the error - fetch_db_tables handles it
cleanup_mysql_results(db_res, cur_table_res, table_res);
......@@ -797,14 +795,15 @@ int load_master_data(THD* thd)
*/
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);
strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name));
// atoi() is ok, since offset is <= 1GB
active_mi->master_log_pos = atoi(row[1]);
if (active_mi->master_log_pos < 4)
active_mi->master_log_pos = 4; // don't hit the magic number
active_mi->rli.pending = 0;
flush_master_info(active_mi);
}
mc_mysql_free_result(master_status_res);
}
......@@ -815,11 +814,35 @@ int load_master_data(THD* thd)
goto err;
}
}
thd->proc_info="purging old relay logs";
if (purge_relay_logs(&active_mi->rli,0 /* not only reset, but also reinit*/,
&errmsg))
{
send_error(&thd->net, 0, "Failed purging old relay logs");
unlock_slave_threads(active_mi);
UNLOCK_ACTIVE_MI;
return 1;
}
pthread_mutex_lock(&active_mi->rli.data_lock);
active_mi->rli.master_log_pos = active_mi->master_log_pos;
strnmov(active_mi->rli.master_log_name,active_mi->master_log_name,
sizeof(active_mi->rli.master_log_name));
pthread_cond_broadcast(&active_mi->rli.data_cond);
pthread_mutex_unlock(&active_mi->rli.data_lock);
thd->proc_info = "starting slave";
if (restart_thread_mask)
{
error=start_slave_threads(0 /* mutex not needed*/,
1 /* wait for start*/,
active_mi,master_info_file,relay_log_info_file,
restart_thread_mask);
}
err:
pthread_mutex_unlock(&LOCK_slave);
if (slave_was_running)
start_slave(0, 0);
unlock_slave_threads(active_mi);
UNLOCK_ACTIVE_MI;
thd->proc_info = 0;
mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
if (!error)
send_ok(&thd->net);
......
This diff is collapsed.
This diff is collapsed.
......@@ -98,7 +98,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
current_linfo = 0;
slave_thread = 0;
slave_proxy_id = 0;
log_seq = 0;
file_id = 0;
cond_count=0;
convert_set=0;
......@@ -119,6 +118,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
where="field list";
server_id = ::server_id;
slave_net = 0;
log_pos = 0;
server_status=SERVER_STATUS_AUTOCOMMIT;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
options=thd_startup_options;
......@@ -216,10 +216,11 @@ THD::~THD()
DBUG_VOID_RETURN;
}
void THD::prepare_to_die()
void THD::awake(bool prepare_to_die)
{
thr_alarm_kill(real_id);
if (prepare_to_die)
killed = 1;
thr_alarm_kill(real_id);
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
#endif
......@@ -228,6 +229,10 @@ void THD::prepare_to_die()
pthread_mutex_lock(&mysys_var->mutex);
if (!system_thread) // Don't abort locks
mysys_var->abort=1;
// this broadcast could be up in the air if the victim thread
// exits the cond in the time between read and broadcast, but that is
// ok since all we want to do is to make the victim thread get out
// of waiting on current_cond
if (mysys_var->current_cond)
{
pthread_mutex_lock(mysys_var->current_mutex);
......
......@@ -21,6 +21,8 @@
#pragma interface /* gcc class implementation */
#endif
// TODO: create log.h and move all the log header stuff there
class Query_log_event;
class Load_log_event;
class Slave_log_event;
......@@ -40,6 +42,8 @@ enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
#define LOG_INFO_FATAL -7
#define LOG_INFO_IN_USE -8
struct st_relay_log_info;
typedef struct st_log_info
{
char log_file_name[FN_REFLEN];
......@@ -64,8 +68,6 @@ class MYSQL_LOG {
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
bool write_error,inited;
uint32 log_seq; // current event sequence number
// needed this for binlog
uint file_id; // current file sequence number for load data infile
// binary logging
bool no_rotate; // for binlog - if log name can never change
......@@ -74,36 +76,52 @@ class MYSQL_LOG {
// purging
enum cache_type io_cache_type;
bool need_start_event;
pthread_cond_t update_cond;
bool no_auto_events; // for relay binlog
friend class Log_event;
public:
MYSQL_LOG();
~MYSQL_LOG();
pthread_mutex_t* get_log_lock() { return &LOCK_log; }
IO_CACHE* get_log_file() { return &log_file; }
void signal_update() { pthread_cond_broadcast(&update_cond);}
void wait_for_update(THD* thd);
void set_need_start_event() { need_start_event = 1; }
void set_index_file_name(const char* index_file_name = 0);
void init(enum_log_type log_type_arg,
enum cache_type io_cache_type_arg = WRITE_CACHE);
enum cache_type io_cache_type_arg = WRITE_CACHE,
bool no_auto_events_arg = 0);
void open(const char *log_name,enum_log_type log_type,
const char *new_name=0);
const char *new_name, enum cache_type io_cache_type_arg,
bool no_auto_events_arg);
void new_file(bool inside_mutex = 0);
bool open_index(int options);
void close_index();
bool write(THD *thd, enum enum_server_command command,const char *format,...);
bool write(THD *thd, enum enum_server_command command,
const char *format,...);
bool write(THD *thd, const char *query, uint query_length,
time_t query_start=0);
bool write(Log_event* event_info); // binary log write
bool write(IO_CACHE *cache);
//v stands for vector
//invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
bool appendv(const char* buf,uint len,...);
int generate_new_name(char *new_name,const char *old_name);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
int purge_first_log(struct st_relay_log_info* rli);
int reset_logs(THD* thd);
void close(bool exiting = 0); // if we are exiting, we also want to close the
// index file
// iterating through the log index file
int find_first_log(LOG_INFO* linfo, const char* log_name);
int find_next_log(LOG_INFO* linfo);
int find_first_log(LOG_INFO* linfo, const char* log_name,
bool need_mutex=1);
int find_next_log(LOG_INFO* linfo, bool need_mutex=1);
int get_current_log(LOG_INFO* linfo);
uint next_file_id();
......@@ -226,33 +244,72 @@ public:
};
/****************************************************************************
** every connection is handled by a thread with a THD
****************************************************************************/
class delayed_insert;
/* For each client connection we create a separate thread with THD serving as
a thread/connection descriptor */
class THD :public ilink {
public:
NET net;
LEX lex;
MEM_ROOT mem_root;
HASH user_vars;
String packet; /* Room for 1 row */
struct sockaddr_in remote;
struct rand_struct rand;
NET net; // client connection descriptor
LEX lex; // parse tree descriptor
MEM_ROOT mem_root; // memory allocation pool
HASH user_vars; // hash for user variables
String packet; // dynamic string buffer used for network I/O
struct sockaddr_in remote; // client socket address
struct rand_struct rand; // used for authentication
/* query points to the current query,
thread_stack is a pointer to the stack frame of handle_one_connection(),
which is called first in the thread for handling a client
*/
char *query,*thread_stack;
/*
host - host of the client
user - user of the client, set to NULL until the user has been read from
the connection
priv_user - not sure why we have it, but it is set to "boot" when we run
with --bootstrap
db - currently selected database
ip - client IP
*/
char *host,*user,*priv_user,*db,*ip;
/* proc_info points to a string that will show in the Info column of
SHOW PROCESSLIST output
host_or_ip points to host if host is available, otherwise points to ip
*/
const char *proc_info, *host_or_ip;
/*
client_capabilities has flags describing what the client can do
sql_mode determines if certain non-standard SQL behaviour should be
enabled
max_packet_length - supposed to be maximum packet length the client
can handle, but it currently appears to be assigned but never used
except for one debugging statement
*/
uint client_capabilities,sql_mode,max_packet_length;
/*
master_access - privillege descriptor mask for system threads
db_access - privillege descriptor mask for regular threads
*/
uint master_access,db_access;
/*
open_tables - list of regular tables in use by this thread
temporary_tables - list of temp tables in use by this thread
handler_tables - list of tables that were opened with HANDLER OPEN
and are still in use by this thread
*/
TABLE *open_tables,*temporary_tables, *handler_tables;
// TODO: document the variables below
MYSQL_LOCK *lock,*locked_tables;
ULL *ull;
struct st_my_thread_var *mysys_var;
enum enum_server_command command;
uint32 server_id;
uint32 log_seq;
uint32 file_id; // for LOAD DATA INFILE
const char *where;
time_t start_time,time_after_lock,user_time;
......@@ -293,15 +350,18 @@ public:
bool system_thread,in_lock_tables,global_read_lock;
bool query_error, bootstrap, cleanup_done;
bool volatile killed;
LOG_INFO* current_linfo;
// if we do a purge of binary logs, log index info of the threads
// that are currently reading it needs to be adjusted. To do that
// each thread that is using LOG_INFO needs to adjust the pointer to it
LOG_INFO* current_linfo;
ulong slave_proxy_id; // in slave thread we need to know in behalf of which
// in slave thread we need to know in behalf of which
// thread the query is being run to replicate temp tables properly
ulong slave_proxy_id;
NET* slave_net; // network connection from slave to master
uint32 log_pos;
THD();
~THD();
......@@ -331,7 +391,7 @@ public:
pthread_mutex_unlock(&active_vio_lock);
}
#endif
void prepare_to_die();
void awake(bool prepare_to_die);
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
const char* msg)
{
......
......@@ -94,7 +94,6 @@ typedef struct st_lex_master_info
{
char* host, *user, *password,*log_file_name;
uint port, connect_retry;
ulong last_log_seq;
ulonglong pos;
ulong server_id;
} LEX_MASTER_INFO;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment