mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Ugly merge! But I am not done yet - there are a number of things I need to fix
before I can push BitKeeper/etc/ignore: auto-union Makefile.am: Auto merged include/my_sys.h: Auto merged libmysqld/lib_sql.cc: Auto merged mysql-test/t/rpl_log.test: Auto merged mysys/mf_iocache.c: Auto merged mysys/mf_iocache2.c: Auto merged mysys/thr_mutex.c: Auto merged sql/item_func.cc: Auto merged sql/lex.h: Auto merged sql/mini_client.cc: Auto merged sql/mini_client.h: Auto merged sql/mysql_priv.h: Auto merged sql/repl_failsafe.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_show.cc: Auto merged sql/stacktrace.c: Auto merged sql/structs.h: Auto merged mysql-test/r/rpl000014.result: merge mysql-test/r/rpl000015.result: merge mysql-test/r/rpl000016.result: merge mysql-test/r/rpl_log.result: merge sql/log.cc: merge sql/log_event.cc: merge sql/log_event.h: merge sql/mysqld.cc: merge sql/slave.cc: merge sql/slave.h: merge sql/sql_class.h: merge sql/sql_parse.cc: merge sql/sql_repl.cc: merge sql/sql_yacc.yy: merge
This commit is contained in:
commit
1e0f2b7a42
39 changed files with 2998 additions and 1568 deletions
|
@ -245,6 +245,7 @@ libmysqld/get_password.c
|
||||||
libmysqld/ha_berkeley.cc
|
libmysqld/ha_berkeley.cc
|
||||||
libmysqld/ha_heap.cc
|
libmysqld/ha_heap.cc
|
||||||
libmysqld/ha_innobase.cc
|
libmysqld/ha_innobase.cc
|
||||||
|
libmysqld/ha_innodb.cc
|
||||||
libmysqld/ha_isam.cc
|
libmysqld/ha_isam.cc
|
||||||
libmysqld/ha_isammrg.cc
|
libmysqld/ha_isammrg.cc
|
||||||
libmysqld/ha_myisam.cc
|
libmysqld/ha_myisam.cc
|
||||||
|
@ -344,7 +345,13 @@ mysql-test/gmon.out
|
||||||
mysql-test/install_test_db
|
mysql-test/install_test_db
|
||||||
mysql-test/mysql-test-run
|
mysql-test/mysql-test-run
|
||||||
mysql-test/r/*.reject
|
mysql-test/r/*.reject
|
||||||
|
mysql-test/r/rpl000002.eval
|
||||||
|
mysql-test/r/rpl000014.eval
|
||||||
|
mysql-test/r/rpl000015.eval
|
||||||
|
mysql-test/r/rpl000016.eval
|
||||||
mysql-test/r/rpl_log.eval
|
mysql-test/r/rpl_log.eval
|
||||||
|
mysql-test/r/slave-running.eval
|
||||||
|
mysql-test/r/slave-stopped.eval
|
||||||
mysql-test/share/mysql
|
mysql-test/share/mysql
|
||||||
mysql-test/var/*
|
mysql-test/var/*
|
||||||
mysql.kdevprj
|
mysql.kdevprj
|
||||||
|
@ -451,4 +458,3 @@ vio/test-ssl
|
||||||
vio/test-sslclient
|
vio/test-sslclient
|
||||||
vio/test-sslserver
|
vio/test-sslserver
|
||||||
vio/viotest-ssl
|
vio/viotest-ssl
|
||||||
libmysqld/ha_innodb.cc
|
|
||||||
|
|
|
@ -75,14 +75,11 @@ bin-dist: all
|
||||||
$(top_builddir)/scripts/make_binary_distribution
|
$(top_builddir)/scripts/make_binary_distribution
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
rm -f TAGS
|
support-files/build-tags
|
||||||
find -not -path \*SCCS\* -and \
|
|
||||||
\( -name \*.cc -or -name \*.h -or -name \*.yy -or -name \*.c \) \
|
|
||||||
-print -exec etags -o TAGS --append {} \;
|
|
||||||
|
|
||||||
.PHONY: init-db bin-dist
|
.PHONY: init-db bin-dist
|
||||||
|
|
||||||
# Test installation
|
# Test installation
|
||||||
|
|
||||||
test:
|
test:
|
||||||
cd mysql-test ; ./mysql-test-run
|
cd mysql-test ; ./mysql-test-run
|
||||||
|
|
||||||
|
|
|
@ -293,35 +293,105 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
|
||||||
|
|
||||||
typedef struct st_io_cache /* Used when cacheing files */
|
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;
|
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;
|
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;
|
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;
|
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
|
#ifdef THREAD
|
||||||
pthread_mutex_t append_buffer_lock;
|
pthread_mutex_t append_buffer_lock;
|
||||||
/* need mutex copying from append buffer to read buffer */
|
/* need mutex copying from append buffer to read buffer */
|
||||||
#endif
|
#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);
|
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);
|
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;
|
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 pre_read;
|
||||||
IO_CACHE_CALLBACK post_read;
|
IO_CACHE_CALLBACK post_read;
|
||||||
IO_CACHE_CALLBACK pre_close;
|
IO_CACHE_CALLBACK pre_close;
|
||||||
void* arg; /* for use by pre/post_read */
|
void* arg; /* for use by pre/post_read */
|
||||||
char *file_name; /* if used with 'open_cached_file' */
|
char *file_name; /* if used with 'open_cached_file' */
|
||||||
char *dir,*prefix;
|
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;
|
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;
|
uint buffer_length,read_length;
|
||||||
myf myflags; /* Flags used to my_read/my_write */
|
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
|
Currently READ_NET is the only one that will use a buffer allocated
|
||||||
somewhere else
|
somewhere else
|
||||||
*/
|
*/
|
||||||
my_bool alloced_buffer;
|
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
|
#ifdef HAVE_AIOWAIT
|
||||||
|
/* as inidicated by ifdef, this is for async I/O, we will have
|
||||||
|
Sinisa comment this some time
|
||||||
|
*/
|
||||||
uint inited;
|
uint inited;
|
||||||
my_off_t aio_read_pos;
|
my_off_t aio_read_pos;
|
||||||
my_aio_result aio_result;
|
my_aio_result aio_result;
|
||||||
|
@ -366,6 +436,8 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
|
||||||
|
|
||||||
#define my_b_tell(info) ((info)->pos_in_file + \
|
#define my_b_tell(info) ((info)->pos_in_file + \
|
||||||
(uint) (*(info)->current_pos - (info)->request_pos))
|
(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 - \
|
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
|
||||||
*(info)->current_pos)
|
*(info)->current_pos)
|
||||||
|
|
|
@ -402,8 +402,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_sent,MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_bytes_received,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_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_io, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_slave, 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_server_id, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_cond_init(&COND_thread_count,NULL);
|
(void) pthread_cond_init(&COND_thread_count,NULL);
|
||||||
|
@ -412,8 +412,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_flush_thread_cache,NULL);
|
||||||
(void) pthread_cond_init(&COND_manager,NULL);
|
(void) pthread_cond_init(&COND_manager,NULL);
|
||||||
(void) pthread_cond_init(&COND_binlog_update, NULL);
|
(void) pthread_cond_init(&COND_binlog_update, NULL);
|
||||||
(void) pthread_cond_init(&COND_slave_stopped, NULL);
|
(void) pthread_cond_init(&COND_slave_log_update, NULL);
|
||||||
(void) pthread_cond_init(&COND_slave_start, 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)))
|
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
|
File Position Binlog_do_db Binlog_ignore_db
|
||||||
master-bin.001 79
|
master-bin.001 79
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 1 master-bin.001 79 Yes 0 0 1
|
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;
|
change master to master_log_pos=73;
|
||||||
slave stop;
|
slave stop;
|
||||||
change master to master_log_pos=73;
|
change master to master_log_pos=73;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 1 master-bin.001 73 No 0 0 1
|
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;
|
slave start;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 1 master-bin.001 73 Yes 0 0 1
|
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;
|
change master to master_log_pos=173;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 1 master-bin.001 173 Yes 0 0 1
|
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;
|
show master status;
|
||||||
File Position Binlog_do_db Binlog_ignore_db
|
File Position Binlog_do_db Binlog_ignore_db
|
||||||
master-bin.001 79
|
master-bin.001 79
|
||||||
|
|
|
@ -4,21 +4,21 @@ File Position Binlog_do_db Binlog_ignore_db
|
||||||
master-bin.001 79
|
master-bin.001 79
|
||||||
reset slave;
|
reset slave;
|
||||||
show slave status;
|
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
|
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 No 0 0 0
|
0 0 0 0 No No 0 0 0
|
||||||
change master to master_host='127.0.0.1';
|
change master to master_host='127.0.0.1';
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 4 No 0 0 0
|
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',
|
change master to master_host='127.0.0.1',master_user='root',
|
||||||
master_password='',master_port=MASTER_PORT;
|
master_password='',master_port=9306;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 4 No 0 0 0
|
127.0.0.1 root 9306 60 4 mysql-relay-bin.001 4 No No 0 0 0
|
||||||
slave start;
|
slave start;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 master-bin.001 79 Yes 0 0 1
|
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;
|
drop table if exists t1;
|
||||||
create table t1 (n int);
|
create table t1 (n int);
|
||||||
insert into t1 values (10),(45),(90);
|
insert into t1 values (10),(45),(90);
|
||||||
|
|
|
@ -2,11 +2,11 @@ slave start;
|
||||||
Could not initialize master info structure, check permisions on master.info
|
Could not initialize master info structure, check permisions on master.info
|
||||||
slave start;
|
slave start;
|
||||||
Could not initialize master info structure, check permisions on master.info
|
Could not initialize master info structure, check permisions on master.info
|
||||||
change master to master_host='127.0.0.1',master_port=MASTER_PORT,
|
change master to master_host='127.0.0.1',master_port=9306,
|
||||||
master_user='root';
|
master_user='root';
|
||||||
Could not initialize master info
|
Could not initialize master info
|
||||||
reset slave;
|
reset slave;
|
||||||
change master to master_host='127.0.0.1',master_port=MASTER_PORT,
|
change master to master_host='127.0.0.1',master_port=9306,
|
||||||
master_user='root';
|
master_user='root';
|
||||||
reset master;
|
reset master;
|
||||||
slave start;
|
slave start;
|
||||||
|
@ -14,8 +14,8 @@ drop table if exists t1;
|
||||||
create table t1 (s text);
|
create table t1 (s text);
|
||||||
insert into t1 values('Could not break slave'),('Tried hard');
|
insert into t1 values('Could not break slave'),('Tried hard');
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 master-bin.001 234 Yes 0 0 3
|
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;
|
select * from t1;
|
||||||
s
|
s
|
||||||
Could not break slave
|
Could not break slave
|
||||||
|
@ -42,8 +42,8 @@ Log_name
|
||||||
master-bin.003
|
master-bin.003
|
||||||
insert into t2 values (65);
|
insert into t2 values (65);
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 master-bin.003 155 Yes 0 0 3
|
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;
|
select * from t2;
|
||||||
m
|
m
|
||||||
34
|
34
|
||||||
|
@ -65,8 +65,8 @@ master-bin.006 445
|
||||||
slave stop;
|
slave stop;
|
||||||
slave start;
|
slave start;
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 60 master-bin.006 445 Yes 0 0 7
|
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;
|
lock tables t3 read;
|
||||||
select count(*) from t3 where n >= 4;
|
select count(*) from t3 where n >= 4;
|
||||||
count(*)
|
count(*)
|
||||||
|
|
|
@ -15,48 +15,48 @@ create table t1 (word char(20) not null);
|
||||||
load data infile '../../std_data/words.dat' into table t1;
|
load data infile '../../std_data/words.dat' into table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
show binlog events;
|
show binlog events;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.001 4 Start 1 1 Server ver: VERSION, Binlog ver: 2
|
master-bin.001 4 Start 1 4 Server ver: 4.0.1-alpha-debug-log, Binlog ver: 3
|
||||||
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
|
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 3 INSERT_ID=1
|
master-bin.001 172 Intvar 1 172 INSERT_ID=1
|
||||||
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
|
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
|
||||||
master-bin.001 263 Query 1 5 use test; drop table t1
|
master-bin.001 263 Query 1 263 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 311 Query 1 311 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 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
|
||||||
master-bin.001 556 Exec_load 1 8 ;file_id=1
|
master-bin.001 556 Exec_load 1 556 ;file_id=1
|
||||||
master-bin.001 579 Query 1 9 use test; drop table t1
|
master-bin.001 579 Query 1 579 use test; drop table t1
|
||||||
show binlog events from 79 limit 1;
|
show binlog events from 79 limit 1;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
|
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;
|
show binlog events from 79 limit 2;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
|
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 3 INSERT_ID=1
|
master-bin.001 172 Intvar 1 172 INSERT_ID=1
|
||||||
show binlog events from 79 limit 2,1;
|
show binlog events from 79 limit 2,1;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
|
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
|
||||||
flush logs;
|
flush logs;
|
||||||
create table t1 (n int);
|
create table t1 (n int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
show binlog events;
|
show binlog events;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.001 4 Start 1 1 Server ver: VERSION, Binlog ver: 2
|
master-bin.001 4 Start 1 4 Server ver: 4.0.1-alpha-debug-log, Binlog ver: 3
|
||||||
master-bin.001 79 Query 1 2 use test; create table t1(n int not null auto_increment primary key)
|
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 3 INSERT_ID=1
|
master-bin.001 172 Intvar 1 172 INSERT_ID=1
|
||||||
master-bin.001 200 Query 1 4 use test; insert into t1 values (NULL)
|
master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL)
|
||||||
master-bin.001 263 Query 1 5 use test; drop table t1
|
master-bin.001 263 Query 1 263 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 311 Query 1 311 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 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81
|
||||||
master-bin.001 556 Exec_load 1 8 ;file_id=1
|
master-bin.001 556 Exec_load 1 556 ;file_id=1
|
||||||
master-bin.001 579 Query 1 9 use test; drop table t1
|
master-bin.001 579 Query 1 579 use test; drop table t1
|
||||||
master-bin.001 627 Rotate 1 10 master-bin.002;pos=4
|
master-bin.001 627 Rotate 1 627 master-bin.002;pos=4
|
||||||
master-bin.001 668 Stop 1 11
|
master-bin.001 668 Stop 1 668
|
||||||
show binlog events in 'master-bin.002';
|
show binlog events in 'master-bin.002';
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
master-bin.002 4 Query 1 1 use test; create table t1 (n int)
|
master-bin.002 4 Query 1 4 use test; create table t1 (n int)
|
||||||
master-bin.002 62 Query 1 2 use test; insert into t1 values (1)
|
master-bin.002 62 Query 1 62 use test; insert into t1 values (1)
|
||||||
master-bin.002 122 Query 1 3 use test; drop table t1
|
master-bin.002 122 Query 1 122 use test; drop table t1
|
||||||
show master logs;
|
show master logs;
|
||||||
Log_name
|
Log_name
|
||||||
master-bin.001
|
master-bin.001
|
||||||
|
@ -67,32 +67,45 @@ Log_name
|
||||||
slave-bin.001
|
slave-bin.001
|
||||||
slave-bin.002
|
slave-bin.002
|
||||||
show binlog events in 'slave-bin.001' from 4;
|
show binlog events in 'slave-bin.001' from 4;
|
||||||
|
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;
|
show binlog events in 'slave-bin.002' from 4;
|
||||||
Log_name Pos Event_type Server_id Log_seq Info
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
slave-bin.002 4 Slave 2 10 host=127.0.0.1,port=MASTER_PORT,log=master-bin.002,pos=4
|
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 1 use test; create table t1 (n int)
|
slave-bin.002 57 Query 1 4 use test; create table t1 (n int)
|
||||||
slave-bin.002 115 Query 1 2 use test; insert into t1 values (1)
|
slave-bin.002 115 Query 1 62 use test; insert into t1 values (1)
|
||||||
slave-bin.002 175 Query 1 3 use test; drop table t1
|
slave-bin.002 175 Query 1 122 use test; drop table t1
|
||||||
show slave status;
|
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
|
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 MASTER_PORT 1 master-bin.002 170 Yes 0 0 3
|
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
|
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
|
Log_name Log_pos
|
||||||
slave-bin.001 132
|
slave-bin.001 132
|
||||||
show new master for slave with master_log_file='master-bin.001' and
|
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
|
Log_name Log_pos
|
||||||
slave-bin.001 225
|
slave-bin.001 225
|
||||||
show new master for slave with master_log_file='master-bin.001' and
|
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
|
Log_name Log_pos
|
||||||
slave-bin.001 439
|
slave-bin.001 439
|
||||||
show new master for slave with master_log_file='master-bin.002' and
|
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
|
Log_name Log_pos
|
||||||
slave-bin.002 57
|
slave-bin.002 57
|
||||||
show new master for slave with master_log_file='master-bin.002' and
|
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
|
Log_name Log_pos
|
||||||
slave-bin.002 223
|
slave-bin.002 223
|
||||||
|
|
8
mysql-test/resolve-stack
Executable file
8
mysql-test/resolve-stack
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#! /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
|
1
mysql-test/t/rpl000016-slave.opt
Normal file
1
mysql-test/t/rpl000016-slave.opt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-O max_binlog_size=2048
|
|
@ -1 +1,2 @@
|
||||||
rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
|
rm -f $MYSQL_TEST_DIR/var/slave-data/master.info
|
||||||
|
rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
rm -f $MYSQL_TEST_DIR/var/slave-data/*relay*
|
||||||
cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF
|
cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF
|
||||||
master-bin.001
|
master-bin.001
|
||||||
4
|
4
|
||||||
|
|
|
@ -46,12 +46,12 @@ show binlog events in 'slave-bin.002' from 4;
|
||||||
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
|
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
|
||||||
show slave status;
|
show slave status;
|
||||||
show new master for slave with master_log_file='master-bin.001' and
|
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
|
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
|
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
|
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
|
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;
|
||||||
|
|
|
@ -122,6 +122,8 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
|
||||||
info->pos_in_file= seek_offset;
|
info->pos_in_file= seek_offset;
|
||||||
info->pre_close = info->pre_read = info->post_read = 0;
|
info->pre_close = info->pre_read = info->post_read = 0;
|
||||||
info->arg = 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->alloced_buffer = 0;
|
||||||
info->buffer=0;
|
info->buffer=0;
|
||||||
info->seek_not_done= test(file >= 0);
|
info->seek_not_done= test(file >= 0);
|
||||||
|
@ -446,11 +448,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||||
info->end_of_file)
|
info->end_of_file)
|
||||||
goto read_append_buffer;
|
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,
|
||||||
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
|
because the write could have moved the file pointer astray
|
||||||
info->seek_not_done=0;
|
*/
|
||||||
}
|
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));
|
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
|
||||||
|
|
||||||
/* now the second stage begins - read from file descriptor */
|
/* now the second stage begins - read from file descriptor */
|
||||||
|
@ -506,6 +510,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||||
memcpy(Buffer,info->buffer,(size_t) length);
|
memcpy(Buffer,info->buffer,(size_t) length);
|
||||||
Count -= length;
|
Count -= length;
|
||||||
Buffer += 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;
|
goto read_append_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,10 +538,13 @@ read_append_buffer:
|
||||||
/* First copy the data to Count */
|
/* First copy the data to Count */
|
||||||
uint len_in_buff = (uint) (info->write_pos - info->append_read_pos);
|
uint len_in_buff = (uint) (info->write_pos - info->append_read_pos);
|
||||||
uint copy_len;
|
uint copy_len;
|
||||||
|
uint transfer_len;
|
||||||
|
|
||||||
DBUG_ASSERT(info->append_read_pos <= info->write_pos);
|
DBUG_ASSERT(info->append_read_pos <= info->write_pos);
|
||||||
DBUG_ASSERT(pos_in_file == info->end_of_file);
|
/*
|
||||||
|
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);
|
copy_len=min(Count, len_in_buff);
|
||||||
memcpy(Buffer, info->append_read_pos, copy_len);
|
memcpy(Buffer, info->append_read_pos, copy_len);
|
||||||
info->append_read_pos += copy_len;
|
info->append_read_pos += copy_len;
|
||||||
|
@ -540,11 +554,12 @@ read_append_buffer:
|
||||||
|
|
||||||
/* Fill read buffer with data from write buffer */
|
/* Fill read buffer with data from write buffer */
|
||||||
memcpy(info->buffer, info->append_read_pos,
|
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_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->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);
|
unlock_append_buffer(info);
|
||||||
return Count ? 1 : 0;
|
return Count ? 1 : 0;
|
||||||
|
@ -886,12 +901,10 @@ int flush_io_cache(IO_CACHE *info)
|
||||||
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
if ((length=(uint) (info->write_pos - info->write_buffer)))
|
||||||
{
|
{
|
||||||
pos_in_file=info->pos_in_file;
|
pos_in_file=info->pos_in_file;
|
||||||
if (append_cache)
|
/* if we have append cache, we always open the file with
|
||||||
{
|
O_APPEND which moves the pos to EOF automatically on every write
|
||||||
pos_in_file=info->end_of_file;
|
*/
|
||||||
info->seek_not_done=1;
|
if (!append_cache && info->seek_not_done)
|
||||||
}
|
|
||||||
if (info->seek_not_done)
|
|
||||||
{ /* File touched, do seek */
|
{ /* File touched, do seek */
|
||||||
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
|
||||||
MY_FILEPOS_ERROR)
|
MY_FILEPOS_ERROR)
|
||||||
|
@ -901,20 +914,24 @@ int flush_io_cache(IO_CACHE *info)
|
||||||
if (!append_cache)
|
if (!append_cache)
|
||||||
info->seek_not_done=0;
|
info->seek_not_done=0;
|
||||||
}
|
}
|
||||||
info->write_pos= info->write_buffer;
|
|
||||||
if (!append_cache)
|
if (!append_cache)
|
||||||
info->pos_in_file+=length;
|
info->pos_in_file+=length;
|
||||||
info->write_end= (info->write_buffer+info->buffer_length-
|
info->write_end= (info->write_buffer+info->buffer_length-
|
||||||
((pos_in_file+length) & (IO_SIZE-1)));
|
((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,
|
if (my_write(info->file,info->write_buffer,length,
|
||||||
info->myflags | MY_NABP))
|
info->myflags | MY_NABP))
|
||||||
info->error= -1;
|
info->error= -1;
|
||||||
else
|
else
|
||||||
info->error= 0;
|
info->error= 0;
|
||||||
set_if_bigger(info->end_of_file,(pos_in_file+length));
|
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);
|
DBUG_RETURN(info->error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,26 @@
|
||||||
|
|
||||||
void my_b_seek(IO_CACHE *info,my_off_t pos)
|
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_ENTER("my_b_seek");
|
||||||
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
|
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))
|
if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
|
||||||
{
|
{
|
||||||
/* The read is in the current buffer; Reuse it */
|
/* The read is in the current buffer; Reuse it */
|
||||||
|
|
|
@ -69,7 +69,8 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
|
||||||
}
|
}
|
||||||
if (mp->count++)
|
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);
|
fflush(stderr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1453,11 +1453,13 @@ longlong Item_master_pos_wait::val_int()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ulong pos = (ulong)args[1]->val_int();
|
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;
|
null_value = 1;
|
||||||
event_count=0;
|
event_count=0;
|
||||||
}
|
}
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
return event_count;
|
return event_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,6 @@ static SYMBOL symbols[] = {
|
||||||
{ "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0},
|
{ "MASTER_HOST", SYM(MASTER_HOST_SYM),0,0},
|
||||||
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_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_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_PASSWORD", SYM(MASTER_PASSWORD_SYM),0,0},
|
||||||
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
|
{ "MASTER_PORT", SYM(MASTER_PORT_SYM),0,0},
|
||||||
{ "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
|
{ "MASTER_SERVER_ID", SYM(MASTER_SERVER_ID_SYM),0,0},
|
||||||
|
|
338
sql/log.cc
338
sql/log.cc
|
@ -1,15 +1,15 @@
|
||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <m_ctype.h> // For test_if_number
|
#include <m_ctype.h> // For test_if_number
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
|
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
|
||||||
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
|
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
|
||||||
|
@ -81,7 +82,7 @@ static int find_uniq_filename(char *name)
|
||||||
|
|
||||||
MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),index_file(-1),
|
MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),index_file(-1),
|
||||||
name(0), log_type(LOG_CLOSED),write_error(0),
|
name(0), log_type(LOG_CLOSED),write_error(0),
|
||||||
inited(0), log_seq(1), file_id(1),no_rotate(0),
|
inited(0), file_id(1),no_rotate(0),
|
||||||
need_start_event(1)
|
need_start_event(1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -112,7 +113,7 @@ void MYSQL_LOG::set_index_file_name(const char* index_file_name)
|
||||||
|
|
||||||
|
|
||||||
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
|
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
|
||||||
{
|
{
|
||||||
if (log_type == LOG_NORMAL)
|
if (log_type == LOG_NORMAL)
|
||||||
fn_format(new_name,log_name,mysql_data_home,"",4);
|
fn_format(new_name,log_name,mysql_data_home,"",4);
|
||||||
else
|
else
|
||||||
|
@ -138,15 +139,18 @@ bool MYSQL_LOG::open_index( int options)
|
||||||
}
|
}
|
||||||
|
|
||||||
void MYSQL_LOG::init(enum_log_type log_type_arg,
|
void MYSQL_LOG::init(enum_log_type log_type_arg,
|
||||||
enum cache_type io_cache_type_arg)
|
enum cache_type io_cache_type_arg,
|
||||||
|
bool no_auto_events_arg)
|
||||||
{
|
{
|
||||||
log_type = log_type_arg;
|
log_type = log_type_arg;
|
||||||
io_cache_type = io_cache_type_arg;
|
io_cache_type = io_cache_type_arg;
|
||||||
|
no_auto_events = no_auto_events_arg;
|
||||||
if (!inited)
|
if (!inited)
|
||||||
{
|
{
|
||||||
inited=1;
|
inited=1;
|
||||||
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
|
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
|
||||||
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
|
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
|
||||||
|
(void) pthread_cond_init(&update_cond, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,32 +164,38 @@ void MYSQL_LOG::close_index()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
||||||
const char *new_name)
|
const char *new_name, enum cache_type io_cache_type_arg,
|
||||||
|
bool no_auto_events_arg)
|
||||||
{
|
{
|
||||||
MY_STAT tmp_stat;
|
MY_STAT tmp_stat;
|
||||||
char buff[512];
|
char buff[512];
|
||||||
File file= -1;
|
File file= -1;
|
||||||
bool do_magic;
|
bool do_magic;
|
||||||
|
int open_flags = O_CREAT | O_APPEND | O_BINARY;
|
||||||
if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name))
|
if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name))
|
||||||
no_rotate = 1;
|
no_rotate = 1;
|
||||||
init(log_type_arg);
|
init(log_type_arg,io_cache_type_arg,no_auto_events_arg);
|
||||||
|
|
||||||
if (!(name=my_strdup(log_name,MYF(MY_WME))))
|
if (!(name=my_strdup(log_name,MYF(MY_WME))))
|
||||||
goto err;
|
goto err;
|
||||||
if (new_name)
|
if (new_name)
|
||||||
strmov(log_file_name,new_name);
|
strmov(log_file_name,new_name);
|
||||||
else if (generate_new_name(log_file_name, name))
|
else if (generate_new_name(log_file_name, name))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (io_cache_type == SEQ_READ_APPEND)
|
||||||
|
open_flags |= O_RDWR;
|
||||||
|
else
|
||||||
|
open_flags |= O_WRONLY;
|
||||||
|
|
||||||
if (log_type == LOG_BIN && !index_file_name[0])
|
if (log_type == LOG_BIN && !index_file_name[0])
|
||||||
fn_format(index_file_name, name, mysql_data_home, ".index", 6);
|
fn_format(index_file_name, name, mysql_data_home, ".index", 6);
|
||||||
|
|
||||||
db[0]=0;
|
db[0]=0;
|
||||||
do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
|
do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
|
||||||
&tmp_stat, MYF(0)));
|
&tmp_stat, MYF(0)));
|
||||||
|
|
||||||
if ((file=my_open(log_file_name,O_CREAT | O_APPEND | O_WRONLY | O_BINARY,
|
if ((file=my_open(log_file_name,open_flags,
|
||||||
MYF(MY_WME | ME_WAITTANG))) < 0 ||
|
MYF(MY_WME | ME_WAITTANG))) < 0 ||
|
||||||
init_io_cache(&log_file, file, IO_SIZE, io_cache_type,
|
init_io_cache(&log_file, file, IO_SIZE, io_cache_type,
|
||||||
my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
|
my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
|
||||||
|
@ -235,11 +245,10 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
||||||
open_index(O_APPEND | O_RDWR | O_CREAT))
|
open_index(O_APPEND | O_RDWR | O_CREAT))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
log_seq = 1;
|
if (need_start_event && !no_auto_events)
|
||||||
if (need_start_event)
|
|
||||||
{
|
{
|
||||||
Start_log_event s;
|
Start_log_event s;
|
||||||
s.set_log_seq(0, this);
|
s.set_log_pos(this);
|
||||||
s.write(&log_file);
|
s.write(&log_file);
|
||||||
need_start_event=0;
|
need_start_event=0;
|
||||||
}
|
}
|
||||||
|
@ -264,9 +273,7 @@ err:
|
||||||
end_io_cache(&log_file);
|
end_io_cache(&log_file);
|
||||||
x_free(name); name=0;
|
x_free(name); name=0;
|
||||||
log_type=LOG_CLOSED;
|
log_type=LOG_CLOSED;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
|
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
|
||||||
|
@ -279,7 +286,8 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if log_name is "" we stop at the first entry
|
// if log_name is "" we stop at the first entry
|
||||||
int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
|
int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name,
|
||||||
|
bool need_mutex)
|
||||||
{
|
{
|
||||||
if (index_file < 0)
|
if (index_file < 0)
|
||||||
return LOG_INFO_INVALID;
|
return LOG_INFO_INVALID;
|
||||||
|
@ -290,7 +298,8 @@ int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
|
||||||
|
|
||||||
// mutex needed because we need to make sure the file pointer does not move
|
// mutex needed because we need to make sure the file pointer does not move
|
||||||
// from under our feet
|
// from under our feet
|
||||||
pthread_mutex_lock(&LOCK_index);
|
if (need_mutex)
|
||||||
|
pthread_mutex_lock(&LOCK_index);
|
||||||
if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
|
if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
|
||||||
0, MYF(MY_WME)))
|
0, MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
|
@ -319,14 +328,15 @@ int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
if (need_mutex)
|
||||||
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
end_io_cache(&io_cache);
|
end_io_cache(&io_cache);
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
|
int MYSQL_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
|
||||||
{
|
{
|
||||||
// mutex needed because we need to make sure the file pointer does not move
|
// mutex needed because we need to make sure the file pointer does not move
|
||||||
// from under our feet
|
// from under our feet
|
||||||
|
@ -335,8 +345,8 @@ int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
|
||||||
char* fname = linfo->log_file_name;
|
char* fname = linfo->log_file_name;
|
||||||
IO_CACHE io_cache;
|
IO_CACHE io_cache;
|
||||||
uint length;
|
uint length;
|
||||||
|
if (need_lock)
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
if (init_io_cache(&io_cache, index_file, IO_SIZE,
|
if (init_io_cache(&io_cache, index_file, IO_SIZE,
|
||||||
READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
|
READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
|
||||||
MYF(MY_WME)))
|
MYF(MY_WME)))
|
||||||
|
@ -354,11 +364,125 @@ int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
if (need_lock)
|
||||||
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
end_io_cache(&io_cache);
|
end_io_cache(&io_cache);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MYSQL_LOG::reset_logs(THD* thd)
|
||||||
|
{
|
||||||
|
LOG_INFO linfo;
|
||||||
|
int error=0;
|
||||||
|
const char* save_name;
|
||||||
|
enum_log_type save_log_type;
|
||||||
|
pthread_mutex_lock(&LOCK_log);
|
||||||
|
if (find_first_log(&linfo,""))
|
||||||
|
{
|
||||||
|
error=1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
my_delete(linfo.log_file_name, MYF(MY_WME));
|
||||||
|
if (find_next_log(&linfo))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
save_name=name;
|
||||||
|
name=0;
|
||||||
|
save_log_type=log_type;
|
||||||
|
close(1);
|
||||||
|
my_delete(index_file_name, MYF(MY_WME));
|
||||||
|
if (thd && !thd->slave_thread)
|
||||||
|
need_start_event=1;
|
||||||
|
open(save_name,save_log_type,0,io_cache_type,no_auto_events);
|
||||||
|
my_free((gptr)save_name,MYF(0));
|
||||||
|
err:
|
||||||
|
pthread_mutex_unlock(&LOCK_log);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli)
|
||||||
|
{
|
||||||
|
// pre-conditions
|
||||||
|
DBUG_ASSERT(is_open());
|
||||||
|
DBUG_ASSERT(index_file >= 0);
|
||||||
|
DBUG_ASSERT(rli->slave_running == 1);
|
||||||
|
DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name));
|
||||||
|
// assume that we have previously read the first log and
|
||||||
|
// stored it in rli->relay_log_name
|
||||||
|
DBUG_ASSERT(rli->linfo.index_file_offset ==
|
||||||
|
strlen(rli->relay_log_name) + 1);
|
||||||
|
|
||||||
|
int tmp_fd;
|
||||||
|
|
||||||
|
|
||||||
|
char* fname, *io_buf;
|
||||||
|
int error = 0;
|
||||||
|
if (!(fname = (char*)my_malloc(IO_SIZE+FN_REFLEN, MYF(MY_WME))))
|
||||||
|
return 1;
|
||||||
|
pthread_mutex_lock(&LOCK_index);
|
||||||
|
my_seek(index_file,rli->linfo.index_file_offset,
|
||||||
|
MY_SEEK_SET, MYF(MY_WME));
|
||||||
|
io_buf = fname + FN_REFLEN;
|
||||||
|
strxmov(fname,rli->relay_log_name,".tmp",NullS);
|
||||||
|
|
||||||
|
if ((tmp_fd = my_open(fname,O_CREAT|O_BINARY|O_RDWR, MYF(MY_WME))) < 0)
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int bytes_read;
|
||||||
|
bytes_read = my_read(index_file, io_buf, IO_SIZE, MYF(0));
|
||||||
|
if (bytes_read < 0) // error
|
||||||
|
{
|
||||||
|
error=1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (!bytes_read)
|
||||||
|
break; // end of file
|
||||||
|
// otherwise, we've read something and need to write it out
|
||||||
|
if (my_write(tmp_fd, io_buf, bytes_read, MYF(MY_WME|MY_NABP)))
|
||||||
|
{
|
||||||
|
error=1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err:
|
||||||
|
if (tmp_fd)
|
||||||
|
my_close(tmp_fd, MYF(MY_WME));
|
||||||
|
if (error)
|
||||||
|
my_delete(fname, MYF(0)); // do not report error if the file is not there
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_close(index_file, MYF(MY_WME));
|
||||||
|
if (my_rename(fname,index_file_name,MYF(MY_WME)) ||
|
||||||
|
(index_file=my_open(index_file_name,O_BINARY|O_RDWR|O_APPEND,
|
||||||
|
MYF(MY_WME)))<0 ||
|
||||||
|
my_delete(rli->relay_log_name, MYF(MY_WME)))
|
||||||
|
error=1;
|
||||||
|
if ((error=find_first_log(&rli->linfo,"",0/*no mutex*/)))
|
||||||
|
{
|
||||||
|
char buff[22];
|
||||||
|
sql_print_error("next log error=%d,offset=%s,log=%s",error,
|
||||||
|
llstr(rli->linfo.index_file_offset,buff),
|
||||||
|
rli->linfo.log_file_name);
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
rli->relay_log_pos = 4;
|
||||||
|
strnmov(rli->relay_log_name,rli->linfo.log_file_name,
|
||||||
|
sizeof(rli->relay_log_name));
|
||||||
|
}
|
||||||
|
// no need to free io_buf because we allocated both fname and io_buf in
|
||||||
|
// one malloc()
|
||||||
|
err2:
|
||||||
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
|
my_free(fname, MYF(MY_WME));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||||
{
|
{
|
||||||
|
@ -373,9 +497,9 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||||
my_off_t purge_offset ;
|
my_off_t purge_offset ;
|
||||||
LINT_INIT(purge_offset);
|
LINT_INIT(purge_offset);
|
||||||
IO_CACHE io_cache;
|
IO_CACHE io_cache;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
|
|
||||||
if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
|
if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
|
||||||
0, MYF(MY_WME)))
|
0, MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
|
@ -388,16 +512,15 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
logs_to_purge_inited = 1;
|
logs_to_purge_inited = 1;
|
||||||
|
|
||||||
if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
|
if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
|
||||||
{
|
{
|
||||||
error = LOG_INFO_MEM;
|
error = LOG_INFO_MEM;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
logs_to_keep_inited = 1;
|
logs_to_keep_inited = 1;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
for(;;)
|
|
||||||
{
|
{
|
||||||
my_off_t init_purge_offset= my_b_tell(&io_cache);
|
my_off_t init_purge_offset= my_b_tell(&io_cache);
|
||||||
if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
|
if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
|
||||||
|
@ -409,19 +532,19 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||||
}
|
}
|
||||||
|
|
||||||
fname[--fname_len]=0; // kill \n
|
fname[--fname_len]=0; // kill \n
|
||||||
if(!memcmp(fname, to_log, fname_len + 1 ))
|
if (!memcmp(fname, to_log, fname_len + 1 ))
|
||||||
{
|
{
|
||||||
found_log = 1;
|
found_log = 1;
|
||||||
purge_offset = init_purge_offset;
|
purge_offset = init_purge_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if one of the logs before the target is in use
|
// if one of the logs before the target is in use
|
||||||
if(!found_log && log_in_use(fname))
|
if (!found_log && log_in_use(fname))
|
||||||
{
|
{
|
||||||
error = LOG_INFO_IN_USE;
|
error = LOG_INFO_IN_USE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(p = sql_memdup(fname, fname_len+1)) ||
|
if (!(p = sql_memdup(fname, fname_len+1)) ||
|
||||||
insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
|
insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
|
||||||
(gptr) &p))
|
(gptr) &p))
|
||||||
|
@ -430,22 +553,22 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end_io_cache(&io_cache);
|
end_io_cache(&io_cache);
|
||||||
if(!found_log)
|
if (!found_log)
|
||||||
{
|
{
|
||||||
error = LOG_INFO_EOF;
|
error = LOG_INFO_EOF;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < logs_to_purge.elements; i++)
|
for (i = 0; i < logs_to_purge.elements; i++)
|
||||||
{
|
{
|
||||||
char* l;
|
char* l;
|
||||||
get_dynamic(&logs_to_purge, (gptr)&l, i);
|
get_dynamic(&logs_to_purge, (gptr)&l, i);
|
||||||
if (my_delete(l, MYF(MY_WME)))
|
if (my_delete(l, MYF(MY_WME)))
|
||||||
sql_print_error("Error deleting %s during purge", l);
|
sql_print_error("Error deleting %s during purge", l);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we get killed -9 here, the sysadmin would have to do a small
|
// if we get killed -9 here, the sysadmin would have to do a small
|
||||||
// vi job on the log index file after restart - otherwise, this should
|
// vi job on the log index file after restart - otherwise, this should
|
||||||
// be safe
|
// be safe
|
||||||
|
@ -461,9 +584,9 @@ during log purge for write");
|
||||||
#else
|
#else
|
||||||
my_close(index_file, MYF(MY_WME));
|
my_close(index_file, MYF(MY_WME));
|
||||||
my_delete(index_file_name, MYF(MY_WME));
|
my_delete(index_file_name, MYF(MY_WME));
|
||||||
if(!(index_file = my_open(index_file_name,
|
if ((index_file = my_open(index_file_name,
|
||||||
O_CREAT | O_BINARY | O_RDWR | O_APPEND,
|
O_CREAT | O_BINARY | O_RDWR | O_APPEND,
|
||||||
MYF(MY_WME))))
|
MYF(MY_WME)))<0)
|
||||||
{
|
{
|
||||||
sql_print_error("Could not re-open the binlog index file \
|
sql_print_error("Could not re-open the binlog index file \
|
||||||
during log purge for write");
|
during log purge for write");
|
||||||
|
@ -471,8 +594,8 @@ during log purge for write");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(i = 0; i < logs_to_keep.elements; i++)
|
for (i = 0; i < logs_to_keep.elements; i++)
|
||||||
{
|
{
|
||||||
char* l;
|
char* l;
|
||||||
get_dynamic(&logs_to_keep, (gptr)&l, i);
|
get_dynamic(&logs_to_keep, (gptr)&l, i);
|
||||||
|
@ -490,15 +613,14 @@ during log purge for write");
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
if(logs_to_purge_inited)
|
if (logs_to_purge_inited)
|
||||||
delete_dynamic(&logs_to_purge);
|
delete_dynamic(&logs_to_purge);
|
||||||
if(logs_to_keep_inited)
|
if (logs_to_keep_inited)
|
||||||
delete_dynamic(&logs_to_keep);
|
delete_dynamic(&logs_to_keep);
|
||||||
end_io_cache(&io_cache);
|
end_io_cache(&io_cache);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// we assume that buf has at least FN_REFLEN bytes alloced
|
// we assume that buf has at least FN_REFLEN bytes alloced
|
||||||
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
|
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
|
||||||
{
|
{
|
||||||
|
@ -509,7 +631,7 @@ void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
|
||||||
int ident_len = (uint) strlen(log_ident);
|
int ident_len = (uint) strlen(log_ident);
|
||||||
if (dir_len + ident_len + 1 > FN_REFLEN)
|
if (dir_len + ident_len + 1 > FN_REFLEN)
|
||||||
return; // protection agains malicious buffer overflow
|
return; // protection agains malicious buffer overflow
|
||||||
|
|
||||||
memcpy(buf, log_file_name, dir_len);
|
memcpy(buf, log_file_name, dir_len);
|
||||||
// copy filename + end null
|
// copy filename + end null
|
||||||
memcpy(buf + dir_len, log_ident, ident_len + 1);
|
memcpy(buf + dir_len, log_ident, ident_len + 1);
|
||||||
|
@ -543,30 +665,36 @@ void MYSQL_LOG::new_file(bool inside_mutex)
|
||||||
}
|
}
|
||||||
if (log_type == LOG_BIN)
|
if (log_type == LOG_BIN)
|
||||||
{
|
{
|
||||||
/*
|
if (!no_auto_events)
|
||||||
We log the whole file name for log file as the user may decide
|
{
|
||||||
to change base names at some point.
|
/*
|
||||||
*/
|
We log the whole file name for log file as the user may decide
|
||||||
THD* thd = current_thd;
|
to change base names at some point.
|
||||||
Rotate_log_event r(thd,new_name+dirname_length(new_name));
|
*/
|
||||||
r.set_log_seq(0, this);
|
THD* thd = current_thd;
|
||||||
|
Rotate_log_event r(thd,new_name+dirname_length(new_name));
|
||||||
|
r.set_log_pos(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This log rotation could have been initiated by a master of
|
This log rotation could have been initiated by a master of
|
||||||
the slave running with log-bin we set the flag on rotate
|
the slave running with log-bin we set the flag on rotate
|
||||||
event to prevent inifinite log rotation loop
|
event to prevent inifinite log rotation loop
|
||||||
*/
|
*/
|
||||||
if (thd && slave_thd && thd == slave_thd)
|
if (thd && thd->slave_thread)
|
||||||
r.flags |= LOG_EVENT_FORCED_ROTATE_F;
|
r.flags |= LOG_EVENT_FORCED_ROTATE_F;
|
||||||
r.write(&log_file);
|
r.write(&log_file);
|
||||||
VOID(pthread_cond_broadcast(&COND_binlog_update));
|
}
|
||||||
|
// update needs to be signaled even if there is no rotate event
|
||||||
|
// log rotation should give the waiting thread a signal to
|
||||||
|
// discover EOF and move on to the next log
|
||||||
|
signal_update();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strmov(new_name, old_name); // Reopen old file name
|
strmov(new_name, old_name); // Reopen old file name
|
||||||
}
|
}
|
||||||
name=0;
|
name=0;
|
||||||
close();
|
close();
|
||||||
open(old_name, log_type, new_name);
|
open(old_name, log_type, new_name, io_cache_type, no_auto_events);
|
||||||
my_free(old_name,MYF(0));
|
my_free(old_name,MYF(0));
|
||||||
last_time=query_start=0;
|
last_time=query_start=0;
|
||||||
write_error=0;
|
write_error=0;
|
||||||
|
@ -575,6 +703,31 @@ void MYSQL_LOG::new_file(bool inside_mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MYSQL_LOG::appendv(const char* buf, uint len,...)
|
||||||
|
{
|
||||||
|
bool error = 0;
|
||||||
|
va_list(args);
|
||||||
|
va_start(args,len);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_log);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (my_b_append(&log_file,buf,len))
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((uint)my_b_append_tell(&log_file) > max_binlog_size)
|
||||||
|
{
|
||||||
|
new_file(1);
|
||||||
|
}
|
||||||
|
} while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
signal_update();
|
||||||
|
pthread_mutex_unlock(&LOCK_log);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
bool MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
||||||
const char *format,...)
|
const char *format,...)
|
||||||
|
@ -661,7 +814,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||||
/* In most cases this is only called if 'is_open()' is true */
|
/* In most cases this is only called if 'is_open()' is true */
|
||||||
bool error=0;
|
bool error=0;
|
||||||
bool should_rotate = 0;
|
bool should_rotate = 0;
|
||||||
|
|
||||||
if (!inited) // Can't use mutex if not init
|
if (!inited) // Can't use mutex if not init
|
||||||
return 0;
|
return 0;
|
||||||
VOID(pthread_mutex_lock(&LOCK_log));
|
VOID(pthread_mutex_lock(&LOCK_log));
|
||||||
|
@ -684,11 +837,12 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
error=1;
|
error=1;
|
||||||
|
// no check for auto events flag here - this write method should
|
||||||
|
// never be called if auto-events are enabled
|
||||||
if (thd && thd->last_insert_id_used)
|
if (thd && thd->last_insert_id_used)
|
||||||
{
|
{
|
||||||
Intvar_log_event e(thd,(uchar)LAST_INSERT_ID_EVENT,thd->last_insert_id);
|
Intvar_log_event e(thd,(uchar)LAST_INSERT_ID_EVENT,thd->last_insert_id);
|
||||||
e.set_log_seq(thd, this);
|
e.set_log_pos(this);
|
||||||
if (thd->server_id)
|
if (thd->server_id)
|
||||||
e.server_id = thd->server_id;
|
e.server_id = thd->server_id;
|
||||||
if (e.write(file))
|
if (e.write(file))
|
||||||
|
@ -697,7 +851,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||||
if (thd && thd->insert_id_used)
|
if (thd && thd->insert_id_used)
|
||||||
{
|
{
|
||||||
Intvar_log_event e(thd,(uchar)INSERT_ID_EVENT,thd->last_insert_id);
|
Intvar_log_event e(thd,(uchar)INSERT_ID_EVENT,thd->last_insert_id);
|
||||||
e.set_log_seq(thd, this);
|
e.set_log_pos(this);
|
||||||
if (thd->server_id)
|
if (thd->server_id)
|
||||||
e.server_id = thd->server_id;
|
e.server_id = thd->server_id;
|
||||||
if (e.write(file))
|
if (e.write(file))
|
||||||
|
@ -712,12 +866,12 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||||
// just in case somebody wants it later
|
// just in case somebody wants it later
|
||||||
thd->query_length = (uint)(p - buf);
|
thd->query_length = (uint)(p - buf);
|
||||||
Query_log_event e(thd, buf);
|
Query_log_event e(thd, buf);
|
||||||
e.set_log_seq(thd, this);
|
e.set_log_pos(this);
|
||||||
if (e.write(file))
|
if (e.write(file))
|
||||||
goto err;
|
goto err;
|
||||||
thd->query_length = save_query_length; // clean up
|
thd->query_length = save_query_length; // clean up
|
||||||
}
|
}
|
||||||
event_info->set_log_seq(thd, this);
|
event_info->set_log_pos(this);
|
||||||
if (event_info->write(file) ||
|
if (event_info->write(file) ||
|
||||||
file == &log_file && flush_io_cache(file))
|
file == &log_file && flush_io_cache(file))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -734,7 +888,7 @@ err:
|
||||||
write_error=1;
|
write_error=1;
|
||||||
}
|
}
|
||||||
if (file == &log_file)
|
if (file == &log_file)
|
||||||
VOID(pthread_cond_broadcast(&COND_binlog_update));
|
signal_update();
|
||||||
}
|
}
|
||||||
if (should_rotate)
|
if (should_rotate)
|
||||||
new_file(1); // inside mutex
|
new_file(1); // inside mutex
|
||||||
|
@ -761,11 +915,11 @@ bool MYSQL_LOG::write(IO_CACHE *cache)
|
||||||
{
|
{
|
||||||
VOID(pthread_mutex_lock(&LOCK_log));
|
VOID(pthread_mutex_lock(&LOCK_log));
|
||||||
bool error=1;
|
bool error=1;
|
||||||
|
|
||||||
if (is_open())
|
if (is_open())
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
|
//QQ: this looks like a bug - why READ_CACHE?
|
||||||
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
||||||
{
|
{
|
||||||
sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno);
|
sql_print_error(ER(ER_ERROR_ON_WRITE), cache->file_name, errno);
|
||||||
|
@ -800,10 +954,10 @@ err:
|
||||||
if (error)
|
if (error)
|
||||||
write_error=1;
|
write_error=1;
|
||||||
else
|
else
|
||||||
VOID(pthread_cond_broadcast(&COND_binlog_update));
|
signal_update();
|
||||||
|
|
||||||
VOID(pthread_mutex_unlock(&LOCK_log));
|
VOID(pthread_mutex_unlock(&LOCK_log));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,21 +1084,37 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MYSQL_LOG:: wait_for_update(THD* thd)
|
||||||
|
{
|
||||||
|
const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log,
|
||||||
|
"Slave: waiting for binlog update");
|
||||||
|
pthread_cond_wait(&update_cond, &LOCK_log);
|
||||||
|
// this is not a bug - we unlock the mutex for the caller, and expect him
|
||||||
|
// to lock it and then not unlock it upon return. This is a rather odd
|
||||||
|
// way of doing things, but this is the cleanest way I could think of to
|
||||||
|
// solve the race deadlock caused by THD::awake() first acquiring mysys_var
|
||||||
|
// mutex and then the current mutex, while wait_for_update being called with
|
||||||
|
// the current mutex already aquired and THD::exit_cond() trying to acquire
|
||||||
|
// mysys_var mutex. We do need the mutex to be acquired prior to the
|
||||||
|
// invocation of wait_for_update in all cases, so mutex acquisition inside
|
||||||
|
// wait_for_update() is not an option
|
||||||
|
pthread_mutex_unlock(&LOCK_log);
|
||||||
|
thd->exit_cond(old_msg);
|
||||||
|
}
|
||||||
|
|
||||||
void MYSQL_LOG::close(bool exiting)
|
void MYSQL_LOG::close(bool exiting)
|
||||||
{ // One can't set log_type here!
|
{ // One can't set log_type here!
|
||||||
if (is_open())
|
if (is_open())
|
||||||
{
|
{
|
||||||
File file=log_file.file;
|
if (log_type == LOG_BIN && !no_auto_events)
|
||||||
if (log_type == LOG_BIN)
|
|
||||||
{
|
{
|
||||||
Stop_log_event s;
|
Stop_log_event s;
|
||||||
s.set_log_seq(0, this);
|
s.set_log_pos(this);
|
||||||
s.write(&log_file);
|
s.write(&log_file);
|
||||||
VOID(pthread_cond_broadcast(&COND_binlog_update));
|
signal_update();
|
||||||
}
|
}
|
||||||
end_io_cache(&log_file);
|
end_io_cache(&log_file);
|
||||||
if (my_close(file,MYF(0)) < 0 && ! write_error)
|
if (my_close(log_file.file,MYF(0)) < 0 && ! write_error)
|
||||||
{
|
{
|
||||||
write_error=1;
|
write_error=1;
|
||||||
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
|
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
|
||||||
|
|
519
sql/log_event.cc
519
sql/log_event.cc
File diff suppressed because it is too large
Load diff
331
sql/log_event.h
331
sql/log_event.h
|
@ -1,15 +1,15 @@
|
||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
#define LOG_READ_TOO_LARGE -7
|
#define LOG_READ_TOO_LARGE -7
|
||||||
|
|
||||||
#define LOG_EVENT_OFFSET 4
|
#define LOG_EVENT_OFFSET 4
|
||||||
#define BINLOG_VERSION 2
|
#define BINLOG_VERSION 3
|
||||||
|
|
||||||
/* we could have used SERVER_VERSION_LENGTH, but this introduces an
|
/* we could have used SERVER_VERSION_LENGTH, but this introduces an
|
||||||
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
|
obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
|
||||||
|
@ -77,7 +77,7 @@ struct sql_ex_info
|
||||||
char opt_flags;
|
char opt_flags;
|
||||||
char empty_flags;
|
char empty_flags;
|
||||||
int cached_new_format;
|
int cached_new_format;
|
||||||
|
|
||||||
// store in new format even if old is possible
|
// store in new format even if old is possible
|
||||||
void force_new_format() { cached_new_format = 1;}
|
void force_new_format() { cached_new_format = 1;}
|
||||||
int data_size() { return new_format() ?
|
int data_size() { return new_format() ?
|
||||||
|
@ -120,7 +120,7 @@ struct sql_ex_info
|
||||||
#define EVENT_TYPE_OFFSET 4
|
#define EVENT_TYPE_OFFSET 4
|
||||||
#define SERVER_ID_OFFSET 5
|
#define SERVER_ID_OFFSET 5
|
||||||
#define EVENT_LEN_OFFSET 9
|
#define EVENT_LEN_OFFSET 9
|
||||||
#define LOG_SEQ_OFFSET 13
|
#define LOG_POS_OFFSET 13
|
||||||
#define FLAGS_OFFSET 17
|
#define FLAGS_OFFSET 17
|
||||||
|
|
||||||
/* start event post-header */
|
/* start event post-header */
|
||||||
|
@ -206,7 +206,7 @@ class THD;
|
||||||
|
|
||||||
extern uint32 server_id;
|
extern uint32 server_id;
|
||||||
|
|
||||||
struct st_master_info;
|
struct st_relay_log_info;
|
||||||
|
|
||||||
class Log_event
|
class Log_event
|
||||||
{
|
{
|
||||||
|
@ -214,7 +214,7 @@ public:
|
||||||
time_t when;
|
time_t when;
|
||||||
ulong exec_time;
|
ulong exec_time;
|
||||||
uint32 server_id;
|
uint32 server_id;
|
||||||
uint32 log_seq;
|
uint32 log_pos;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
int cached_event_len;
|
int cached_event_len;
|
||||||
char* temp_buf;
|
char* temp_buf;
|
||||||
|
@ -231,7 +231,7 @@ public:
|
||||||
{
|
{
|
||||||
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
||||||
}
|
}
|
||||||
|
|
||||||
int write(IO_CACHE* file);
|
int write(IO_CACHE* file);
|
||||||
int write_header(IO_CACHE* file);
|
int write_header(IO_CACHE* file);
|
||||||
virtual int write_data(IO_CACHE* file)
|
virtual int write_data(IO_CACHE* file)
|
||||||
|
@ -244,51 +244,55 @@ public:
|
||||||
virtual bool is_valid() = 0;
|
virtual bool is_valid() = 0;
|
||||||
virtual bool get_cache_stmt() { return 0; }
|
virtual bool get_cache_stmt() { return 0; }
|
||||||
Log_event(const char* buf, bool old_format);
|
Log_event(const char* buf, bool old_format);
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Log_event(THD* thd_arg, uint16 flags_arg = 0);
|
||||||
|
#endif
|
||||||
virtual ~Log_event() { free_temp_buf();}
|
virtual ~Log_event() { free_temp_buf();}
|
||||||
void register_temp_buf(char* buf) { temp_buf = buf; }
|
void register_temp_buf(char* buf) { temp_buf = buf; }
|
||||||
void free_temp_buf()
|
void free_temp_buf()
|
||||||
{
|
|
||||||
if (temp_buf)
|
|
||||||
{
|
{
|
||||||
my_free(temp_buf, MYF(0));
|
if (temp_buf)
|
||||||
temp_buf = 0;
|
{
|
||||||
|
my_free(temp_buf, MYF(0));
|
||||||
|
temp_buf = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
virtual int get_data_size() { return 0;}
|
virtual int get_data_size() { return 0;}
|
||||||
virtual int get_data_body_offset() { return 0; }
|
virtual int get_data_body_offset() { return 0; }
|
||||||
int get_event_len() { return cached_event_len ? cached_event_len :
|
int get_event_len() { return cached_event_len ? cached_event_len :
|
||||||
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()); }
|
(cached_event_len = LOG_EVENT_HEADER_LEN + get_data_size()); }
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
|
virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
|
||||||
|
void print_timestamp(FILE* file, time_t *ts = 0);
|
||||||
|
void print_header(FILE* file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
// if mutex is 0, the read will proceed without mutex
|
||||||
|
static Log_event* read_log_event(IO_CACHE* file,
|
||||||
|
pthread_mutex_t* log_lock,
|
||||||
|
bool old_format);
|
||||||
|
#else // avoid having to link mysqlbinlog against libpthread
|
||||||
|
static Log_event* read_log_event(IO_CACHE* file, bool old_format);
|
||||||
|
#endif
|
||||||
static Log_event* read_log_event(const char* buf, int event_len,
|
static Log_event* read_log_event(const char* buf, int event_len,
|
||||||
const char **error, bool old_format);
|
const char **error, bool old_format);
|
||||||
const char* get_type_str();
|
const char* get_type_str();
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
// if mutex is 0, the read will proceed without mutex
|
|
||||||
Log_event(THD* thd_arg, uint16 flags_arg = 0);
|
|
||||||
static Log_event* read_log_event(IO_CACHE* file,
|
|
||||||
pthread_mutex_t* log_lock,
|
|
||||||
bool old_format);
|
|
||||||
static int read_log_event(IO_CACHE* file, String* packet,
|
static int read_log_event(IO_CACHE* file, String* packet,
|
||||||
pthread_mutex_t* log_lock);
|
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);
|
virtual void pack_info(String* packet);
|
||||||
int net_send(THD* thd, const char* log_name, my_off_t pos);
|
int net_send(THD* thd, const char* log_name, my_off_t pos);
|
||||||
static void init_show_field_list(List<Item>* field_list);
|
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()
|
virtual const char* get_db()
|
||||||
{
|
{
|
||||||
return thd ? thd->db : 0;
|
return thd ? thd->db : 0;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// avoid having to link mysqlbinlog against libpthread
|
|
||||||
static Log_event* read_log_event(IO_CACHE* file, bool old_format);
|
|
||||||
|
|
||||||
virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
|
|
||||||
void print_timestamp(FILE* file, time_t *ts = 0);
|
|
||||||
void print_header(FILE* file);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,26 +303,21 @@ protected:
|
||||||
public:
|
public:
|
||||||
const char* query;
|
const char* query;
|
||||||
const char* db;
|
const char* db;
|
||||||
/*
|
uint32 q_len; // if we already know the length of the query string
|
||||||
If we already know the length of the query string
|
// we pass it here, so we would not have to call strlen()
|
||||||
we pass it here, so we would not have to call strlen()
|
// otherwise, set it to 0, in which case, we compute it with strlen()
|
||||||
otherwise, set it to 0, in which case, we compute it with strlen()
|
|
||||||
*/
|
|
||||||
uint32 q_len;
|
|
||||||
uint32 db_len;
|
uint32 db_len;
|
||||||
uint16 error_code;
|
uint16 error_code;
|
||||||
ulong thread_id;
|
ulong thread_id;
|
||||||
#ifndef MYSQL_CLIENT
|
#if !defined(MYSQL_CLIENT)
|
||||||
bool cache_stmt;
|
bool cache_stmt;
|
||||||
|
|
||||||
Query_log_event(THD* thd_arg, const char* query_arg,
|
Query_log_event(THD* thd_arg, const char* query_arg,
|
||||||
bool using_trans=0);
|
bool using_trans=0);
|
||||||
const char* get_db() { return db; }
|
const char* get_db() { return db; }
|
||||||
void pack_info(String* packet);
|
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; }
|
bool get_cache_stmt() { return cache_stmt; }
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Query_log_event(const char* buf, int event_len, bool old_format);
|
Query_log_event(const char* buf, int event_len, bool old_format);
|
||||||
|
@ -341,6 +340,9 @@ public:
|
||||||
+ 2 // error_code
|
+ 2 // error_code
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class Slave_log_event: public Log_event
|
class Slave_log_event: public Log_event
|
||||||
|
@ -350,22 +352,24 @@ protected:
|
||||||
void init_from_mem_pool(int data_size);
|
void init_from_mem_pool(int data_size);
|
||||||
public:
|
public:
|
||||||
char* master_host;
|
char* master_host;
|
||||||
char* master_log;
|
|
||||||
ulonglong master_pos;
|
|
||||||
int master_host_len;
|
int master_host_len;
|
||||||
int master_log_len;
|
|
||||||
uint16 master_port;
|
uint16 master_port;
|
||||||
|
char* master_log;
|
||||||
|
int master_log_len;
|
||||||
|
ulonglong master_pos;
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
|
||||||
|
void pack_info(String* packet);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
|
|
||||||
Slave_log_event(const char* buf, int event_len);
|
Slave_log_event(const char* buf, int event_len);
|
||||||
~Slave_log_event();
|
~Slave_log_event();
|
||||||
int get_data_size();
|
int get_data_size();
|
||||||
bool is_valid() { return master_host != 0; }
|
bool is_valid() { return master_host != 0; }
|
||||||
Log_event_type get_type_code() { return SLAVE_EVENT; }
|
Log_event_type get_type_code() { return SLAVE_EVENT; }
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Slave_log_event(THD* thd_arg, struct st_master_info* mi);
|
|
||||||
void pack_info(String* packet);
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
int write_data(IO_CACHE* file );
|
int write_data(IO_CACHE* file );
|
||||||
|
@ -378,37 +382,36 @@ protected:
|
||||||
int copy_log_event(const char *buf, ulong event_len, bool old_format);
|
int copy_log_event(const char *buf, ulong event_len, bool old_format);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const char* fields;
|
|
||||||
const uchar* field_lens;
|
|
||||||
const char* table_name;
|
|
||||||
const char* db;
|
|
||||||
const char* fname;
|
|
||||||
ulong thread_id;
|
ulong thread_id;
|
||||||
uint32 table_name_len;
|
uint32 table_name_len;
|
||||||
uint32 db_len;
|
uint32 db_len;
|
||||||
uint32 fname_len;
|
uint32 fname_len;
|
||||||
uint32 num_fields;
|
uint32 num_fields;
|
||||||
|
const char* fields;
|
||||||
|
const uchar* field_lens;
|
||||||
uint32 field_block_len;
|
uint32 field_block_len;
|
||||||
|
|
||||||
|
const char* table_name;
|
||||||
|
const char* db;
|
||||||
|
const char* fname;
|
||||||
uint32 skip_lines;
|
uint32 skip_lines;
|
||||||
sql_ex_info sql_ex;
|
sql_ex_info sql_ex;
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#if !defined(MYSQL_CLIENT)
|
||||||
String field_lens_buf;
|
String field_lens_buf;
|
||||||
String fields_buf;
|
String fields_buf;
|
||||||
|
|
||||||
Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
||||||
const char* table_name_arg,
|
const char* table_name_arg,
|
||||||
List<Item>& fields_arg, enum enum_duplicates handle_dup);
|
List<Item>& fields_arg, enum enum_duplicates handle_dup);
|
||||||
void set_fields(List<Item> &fields_arg);
|
void set_fields(List<Item> &fields_arg);
|
||||||
void pack_info(String* packet);
|
void pack_info(String* packet);
|
||||||
const char* get_db() { return db; }
|
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);
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Load_log_event(const char* buf, int event_len, bool old_format);
|
Load_log_event(const char* buf, int event_len, bool old_format);
|
||||||
|
@ -431,6 +434,9 @@ public:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
|
int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char server_version[SERVER_VERSION_LENGTH];
|
extern char server_version[SERVER_VERSION_LENGTH];
|
||||||
|
@ -441,7 +447,13 @@ public:
|
||||||
uint32 created;
|
uint32 created;
|
||||||
uint16 binlog_version;
|
uint16 binlog_version;
|
||||||
char server_version[ST_SERVER_VER_LEN];
|
char server_version[ST_SERVER_VER_LEN];
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION)
|
||||||
|
{
|
||||||
|
created = (uint32) when;
|
||||||
|
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Start_log_event(const char* buf, bool old_format);
|
Start_log_event(const char* buf, bool old_format);
|
||||||
~Start_log_event() {}
|
~Start_log_event() {}
|
||||||
Log_event_type get_type_code() { return START_EVENT;}
|
Log_event_type get_type_code() { return START_EVENT;}
|
||||||
|
@ -452,14 +464,10 @@ public:
|
||||||
return START_HEADER_LEN;
|
return START_HEADER_LEN;
|
||||||
}
|
}
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Start_log_event() :Log_event((THD*)0),binlog_version(BINLOG_VERSION)
|
|
||||||
{
|
|
||||||
created = (uint32) when;
|
|
||||||
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
|
|
||||||
}
|
|
||||||
void pack_info(String* packet);
|
void pack_info(String* packet);
|
||||||
int exec_event(struct st_master_info* mi);
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
#else
|
#endif
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -469,7 +477,11 @@ class Intvar_log_event: public Log_event
|
||||||
public:
|
public:
|
||||||
ulonglong val;
|
ulonglong val;
|
||||||
uchar type;
|
uchar type;
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
|
||||||
|
:Log_event(thd_arg),val(val_arg),type(type_arg)
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
Intvar_log_event(const char* buf, bool old_format);
|
Intvar_log_event(const char* buf, bool old_format);
|
||||||
~Intvar_log_event() {}
|
~Intvar_log_event() {}
|
||||||
Log_event_type get_type_code() { return INTVAR_EVENT;}
|
Log_event_type get_type_code() { return INTVAR_EVENT;}
|
||||||
|
@ -478,12 +490,11 @@ public:
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
bool is_valid() { return 1; }
|
bool is_valid() { return 1; }
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
|
|
||||||
:Log_event(thd_arg),val(val_arg),type(type_arg)
|
|
||||||
{}
|
|
||||||
void pack_info(String* packet);
|
void pack_info(String* packet);
|
||||||
int exec_event(struct st_master_info* mi);
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -491,6 +502,10 @@ public:
|
||||||
class Stop_log_event: public Log_event
|
class Stop_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Stop_log_event() :Log_event((THD*)0)
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
Stop_log_event(const char* buf, bool old_format):Log_event(buf,
|
Stop_log_event(const char* buf, bool old_format):Log_event(buf,
|
||||||
old_format)
|
old_format)
|
||||||
{
|
{
|
||||||
|
@ -498,11 +513,11 @@ public:
|
||||||
~Stop_log_event() {}
|
~Stop_log_event() {}
|
||||||
Log_event_type get_type_code() { return STOP_EVENT;}
|
Log_event_type get_type_code() { return STOP_EVENT;}
|
||||||
bool is_valid() { return 1; }
|
bool is_valid() { return 1; }
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Stop_log_event() :Log_event((THD*)0) {}
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -510,10 +525,19 @@ class Rotate_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const char* new_log_ident;
|
const char* new_log_ident;
|
||||||
|
uchar ident_len;
|
||||||
ulonglong pos;
|
ulonglong pos;
|
||||||
uint8 ident_len;
|
|
||||||
bool alloced;
|
bool alloced;
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
|
||||||
|
uint ident_len_arg = 0,ulonglong pos_arg = 4) :
|
||||||
|
Log_event(thd_arg),
|
||||||
|
new_log_ident(new_log_ident_arg),
|
||||||
|
ident_len(ident_len_arg ? ident_len_arg :
|
||||||
|
(uint) strlen(new_log_ident_arg)), pos(pos_arg),
|
||||||
|
alloced(0)
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
Rotate_log_event(const char* buf, int event_len, bool old_format);
|
Rotate_log_event(const char* buf, int event_len, bool old_format);
|
||||||
~Rotate_log_event()
|
~Rotate_log_event()
|
||||||
{
|
{
|
||||||
|
@ -524,88 +548,77 @@ public:
|
||||||
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
|
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
|
||||||
bool is_valid() { return new_log_ident != 0; }
|
bool is_valid() { return new_log_ident != 0; }
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
|
|
||||||
uint8 ident_len_arg = 0,ulonglong pos_arg = 4) :
|
|
||||||
Log_event(thd_arg), new_log_ident(new_log_ident_arg),
|
|
||||||
pos(pos_arg),
|
|
||||||
ident_len(ident_len_arg ? ident_len_arg :
|
|
||||||
(uint8) strlen(new_log_ident_arg)),
|
|
||||||
alloced(0)
|
|
||||||
{}
|
|
||||||
void pack_info(String* packet);
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
void pack_info(String* packet);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* the classes below are for the new LOAD DATA INFILE logging */
|
/* the classes below are for the new LOAD DATA INFILE logging */
|
||||||
|
|
||||||
class Create_file_log_event: public Load_log_event
|
class Create_file_log_event: public Load_log_event
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/*
|
// pretend we are Load event, so we can write out just
|
||||||
Pretend we are Load event, so we can write out just
|
// our Load part - used on the slave when writing event out to
|
||||||
our Load part - used on the slave when writing event out to
|
// SQL_LOAD-*.info file
|
||||||
SQL_LOAD-*.info file
|
|
||||||
*/
|
|
||||||
bool fake_base;
|
bool fake_base;
|
||||||
public:
|
public:
|
||||||
char* block;
|
char* block;
|
||||||
uint block_len;
|
uint block_len;
|
||||||
uint file_id;
|
uint file_id;
|
||||||
|
|
||||||
Create_file_log_event(const char* buf, int event_len);
|
|
||||||
~Create_file_log_event()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Log_event_type get_type_code()
|
|
||||||
{
|
|
||||||
return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
|
|
||||||
}
|
|
||||||
int get_data_size()
|
|
||||||
{
|
|
||||||
return (fake_base ? Load_log_event::get_data_size() :
|
|
||||||
Load_log_event::get_data_size() +
|
|
||||||
4 + 1 + block_len);
|
|
||||||
}
|
|
||||||
int get_data_body_offset()
|
|
||||||
{
|
|
||||||
return (fake_base ? LOAD_EVENT_OVERHEAD:
|
|
||||||
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN);
|
|
||||||
}
|
|
||||||
bool is_valid() { return block != 0; }
|
|
||||||
int write_data_header(IO_CACHE* file);
|
|
||||||
int write_data_body(IO_CACHE* file);
|
|
||||||
/*
|
|
||||||
Cut out Create_file extentions and write it as Load event - used on the
|
|
||||||
slave.
|
|
||||||
*/
|
|
||||||
int write_base(IO_CACHE* file);
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
|
||||||
const char* table_name_arg,
|
const char* table_name_arg,
|
||||||
List<Item>& fields_arg,
|
List<Item>& fields_arg,
|
||||||
enum enum_duplicates handle_dup,
|
enum enum_duplicates handle_dup,
|
||||||
char* block_arg, uint block_len_arg);
|
char* block_arg, uint block_len_arg);
|
||||||
void pack_info(String* packet);
|
#endif
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
Create_file_log_event(const char* buf, int event_len);
|
||||||
|
~Create_file_log_event()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Log_event_type get_type_code()
|
||||||
|
{
|
||||||
|
return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
|
||||||
|
}
|
||||||
|
int get_data_size() { return fake_base ? Load_log_event::get_data_size() :
|
||||||
|
Load_log_event::get_data_size() +
|
||||||
|
4 + 1 + block_len;}
|
||||||
|
int get_data_body_offset() { return fake_base ? LOAD_EVENT_OVERHEAD:
|
||||||
|
LOAD_EVENT_OVERHEAD + CREATE_FILE_HEADER_LEN; }
|
||||||
|
bool is_valid() { return block != 0; }
|
||||||
|
int write_data_header(IO_CACHE* file);
|
||||||
|
int write_data_body(IO_CACHE* file);
|
||||||
|
int write_base(IO_CACHE* file); // cut out Create_file extentions and
|
||||||
|
// write it as Load event - used on the slave
|
||||||
|
|
||||||
|
#ifdef MYSQL_CLIENT
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
void pack_info(String* packet);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Append_block_log_event: public Log_event
|
class Append_block_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
char* block;
|
char* block;
|
||||||
uint block_len;
|
uint block_len;
|
||||||
uint file_id;
|
uint file_id;
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Append_block_log_event(THD* thd, char* block_arg,
|
||||||
|
uint block_len_arg);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
|
|
||||||
Append_block_log_event(const char* buf, int event_len);
|
Append_block_log_event(const char* buf, int event_len);
|
||||||
~Append_block_log_event()
|
~Append_block_log_event()
|
||||||
{
|
{
|
||||||
|
@ -615,22 +628,23 @@ public:
|
||||||
bool is_valid() { return block != 0; }
|
bool is_valid() { return block != 0; }
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Append_block_log_event(THD* thd, char* block_arg,
|
|
||||||
uint block_len_arg);
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
void pack_info(String* packet);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
void pack_info(String* packet);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Delete_file_log_event: public Log_event
|
class Delete_file_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint file_id;
|
uint file_id;
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Delete_file_log_event(THD* thd);
|
||||||
|
#endif
|
||||||
|
|
||||||
Delete_file_log_event(const char* buf, int event_len);
|
Delete_file_log_event(const char* buf, int event_len);
|
||||||
~Delete_file_log_event()
|
~Delete_file_log_event()
|
||||||
{
|
{
|
||||||
|
@ -640,20 +654,24 @@ public:
|
||||||
bool is_valid() { return file_id != 0; }
|
bool is_valid() { return file_id != 0; }
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Delete_file_log_event(THD* thd);
|
|
||||||
void pack_info(String* packet);
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
void pack_info(String* packet);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class Execute_load_log_event: public Log_event
|
class Execute_load_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint file_id;
|
uint file_id;
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
Execute_load_log_event(THD* thd);
|
||||||
|
#endif
|
||||||
|
|
||||||
Execute_load_log_event(const char* buf, int event_len);
|
Execute_load_log_event(const char* buf, int event_len);
|
||||||
~Execute_load_log_event()
|
~Execute_load_log_event()
|
||||||
{
|
{
|
||||||
|
@ -663,13 +681,16 @@ public:
|
||||||
bool is_valid() { return file_id != 0; }
|
bool is_valid() { return file_id != 0; }
|
||||||
int write_data(IO_CACHE* file);
|
int write_data(IO_CACHE* file);
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
Execute_load_log_event(THD* thd);
|
|
||||||
void pack_info(String* packet);
|
|
||||||
int exec_event(struct st_master_info* mi);
|
|
||||||
#else
|
|
||||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
void pack_info(String* packet);
|
||||||
|
int exec_event(struct st_relay_log_info* rli);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LOG_EVENT_H */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ static MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
||||||
my_bool default_value,
|
my_bool default_value,
|
||||||
my_bool long_flag_protocol);
|
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 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 int mc_send_file_to_server(MYSQL *mysql, const char *filename);
|
||||||
|
@ -194,8 +194,7 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
|
||||||
** Init MySQL structure or allocate one
|
** Init MySQL structure or allocate one
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
MYSQL * STDCALL
|
MYSQL *mc_mysql_init(MYSQL *mysql)
|
||||||
mc_mysql_init(MYSQL *mysql)
|
|
||||||
{
|
{
|
||||||
init_client_errs();
|
init_client_errs();
|
||||||
if (!mysql)
|
if (!mysql)
|
||||||
|
@ -217,7 +216,7 @@ mc_mysql_init(MYSQL *mysql)
|
||||||
** Shut down connection
|
** Shut down connection
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static void
|
void
|
||||||
mc_end_server(MYSQL *mysql)
|
mc_end_server(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mc_end_server");
|
DBUG_ENTER("mc_end_server");
|
||||||
|
@ -339,7 +338,7 @@ static int mc_sock_connect(my_socket s, const struct sockaddr *name,
|
||||||
** or packet is an error message
|
** or packet is an error message
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
ulong STDCALL
|
ulong
|
||||||
mc_net_safe_read(MYSQL *mysql)
|
mc_net_safe_read(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
|
@ -400,17 +399,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;
|
return (mysql)->net.last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int STDCALL mc_mysql_errno(MYSQL *mysql)
|
int mc_mysql_errno(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
return (mysql)->net.last_errno;
|
return (mysql)->net.last_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
|
my_bool mc_mysql_reconnect(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
MYSQL tmp_mysql;
|
MYSQL tmp_mysql;
|
||||||
DBUG_ENTER("mc_mysql_reconnect");
|
DBUG_ENTER("mc_mysql_reconnect");
|
||||||
|
@ -440,7 +439,7 @@ my_bool STDCALL mc_mysql_reconnect(MYSQL *mysql)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int STDCALL
|
int
|
||||||
mc_simple_command(MYSQL *mysql,enum enum_server_command command,
|
mc_simple_command(MYSQL *mysql,enum enum_server_command command,
|
||||||
const char *arg, uint length, my_bool skipp_check)
|
const char *arg, uint length, my_bool skipp_check)
|
||||||
{
|
{
|
||||||
|
@ -493,7 +492,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,
|
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
||||||
const char *passwd, const char *db,
|
const char *passwd, const char *db,
|
||||||
uint port, const char *unix_socket,uint client_flag)
|
uint port, const char *unix_socket,uint client_flag)
|
||||||
|
@ -844,7 +843,7 @@ error:
|
||||||
** NB! Errors are not reported until you do mysql_real_connect.
|
** NB! Errors are not reported until you do mysql_real_connect.
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
*/
|
*/
|
||||||
int STDCALL
|
int
|
||||||
mysql_ssl_clear(MYSQL *mysql)
|
mysql_ssl_clear(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
@ -867,7 +866,7 @@ mysql_ssl_clear(MYSQL *mysql)
|
||||||
** If handle is alloced by mysql connect free it.
|
** If handle is alloced by mysql connect free it.
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
void STDCALL
|
void
|
||||||
mc_mysql_close(MYSQL *mysql)
|
mc_mysql_close(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_close");
|
DBUG_ENTER("mysql_close");
|
||||||
|
@ -898,7 +897,7 @@ mc_mysql_close(MYSQL *mysql)
|
||||||
DBUG_VOID_RETURN;
|
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_ENTER("mc_mysql_free_result");
|
||||||
DBUG_PRINT("enter",("mysql_res: %lx",result));
|
DBUG_PRINT("enter",("mysql_res: %lx",result));
|
||||||
|
@ -976,13 +975,13 @@ mc_unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int STDCALL
|
int
|
||||||
mc_mysql_send_query(MYSQL* mysql, const char* query, uint length)
|
mc_mysql_send_query(MYSQL* mysql, const char* query, uint length)
|
||||||
{
|
{
|
||||||
return mc_simple_command(mysql, COM_QUERY, query, length, 1);
|
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;
|
uchar *pos;
|
||||||
ulong field_count;
|
ulong field_count;
|
||||||
|
@ -1030,7 +1029,7 @@ get_info:
|
||||||
DBUG_RETURN(0);
|
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_ENTER("mysql_real_query");
|
||||||
DBUG_PRINT("enter",("handle: %lx",mysql));
|
DBUG_PRINT("enter",("handle: %lx",mysql));
|
||||||
|
@ -1281,17 +1280,17 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row,
|
||||||
return 0;
|
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;
|
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;
|
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;
|
MYSQL_ROWS *tmp=0;
|
||||||
DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
|
DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
|
||||||
|
@ -1301,7 +1300,7 @@ void STDCALL mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
|
||||||
result->data_cursor = tmp;
|
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");
|
DBUG_ENTER("mc_mysql_fetch_row");
|
||||||
if (!res->data)
|
if (!res->data)
|
||||||
|
@ -1336,7 +1335,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;
|
int error;
|
||||||
DBUG_ENTER("mysql_select_db");
|
DBUG_ENTER("mysql_select_db");
|
||||||
|
@ -1350,7 +1349,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;
|
MYSQL_RES *result;
|
||||||
DBUG_ENTER("mysql_store_result");
|
DBUG_ENTER("mysql_store_result");
|
||||||
|
|
|
@ -18,40 +18,34 @@
|
||||||
#define _MINI_CLIENT_H
|
#define _MINI_CLIENT_H
|
||||||
|
|
||||||
|
|
||||||
MYSQL* STDCALL
|
MYSQL* mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
||||||
mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
|
||||||
const char *passwd, const char *db,
|
const char *passwd, const char *db,
|
||||||
uint port, const char *unix_socket,uint client_flag);
|
uint port, const char *unix_socket,uint client_flag);
|
||||||
|
|
||||||
int STDCALL
|
int mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||||
mc_simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
|
||||||
uint length, my_bool skipp_check);
|
uint length, my_bool skipp_check);
|
||||||
void STDCALL
|
void mc_mysql_close(MYSQL *mysql);
|
||||||
mc_mysql_close(MYSQL *mysql);
|
|
||||||
|
|
||||||
MYSQL * STDCALL
|
MYSQL * mc_mysql_init(MYSQL *mysql);
|
||||||
mc_mysql_init(MYSQL *mysql);
|
|
||||||
|
|
||||||
void STDCALL
|
void mc_mysql_debug(const char *debug);
|
||||||
mc_mysql_debug(const char *debug);
|
|
||||||
|
|
||||||
ulong STDCALL
|
ulong mc_net_safe_read(MYSQL *mysql);
|
||||||
mc_net_safe_read(MYSQL *mysql);
|
|
||||||
|
|
||||||
char * STDCALL mc_mysql_error(MYSQL *mysql);
|
char * mc_mysql_error(MYSQL *mysql);
|
||||||
int STDCALL mc_mysql_errno(MYSQL *mysql);
|
int mc_mysql_errno(MYSQL *mysql);
|
||||||
my_bool STDCALL mc_mysql_reconnect(MYSQL* mysql);
|
my_bool mc_mysql_reconnect(MYSQL* mysql);
|
||||||
|
|
||||||
int STDCALL mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
|
int mc_mysql_send_query(MYSQL* mysql, const char* query, uint length);
|
||||||
int STDCALL mc_mysql_read_query_result(MYSQL *mysql);
|
int mc_mysql_read_query_result(MYSQL *mysql);
|
||||||
int STDCALL mc_mysql_query(MYSQL *mysql, const char *query, uint length);
|
int mc_mysql_query(MYSQL *mysql, const char *query, uint length);
|
||||||
MYSQL_RES * STDCALL mc_mysql_store_result(MYSQL *mysql);
|
MYSQL_RES * mc_mysql_store_result(MYSQL *mysql);
|
||||||
void STDCALL mc_mysql_free_result(MYSQL_RES *result);
|
void mc_mysql_free_result(MYSQL_RES *result);
|
||||||
void STDCALL mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row);
|
void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row);
|
||||||
my_ulonglong STDCALL mc_mysql_num_rows(MYSQL_RES *res);
|
my_ulonglong mc_mysql_num_rows(MYSQL_RES *res);
|
||||||
unsigned int STDCALL mc_mysql_num_fields(MYSQL_RES *res);
|
unsigned int mc_mysql_num_fields(MYSQL_RES *res);
|
||||||
MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res);
|
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);
|
||||||
|
void mc_end_server(MYSQL *mysql);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -540,6 +540,10 @@ void sql_print_error(const char *format,...)
|
||||||
__attribute__ ((format (printf, 1, 2)));
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
bool fn_format_relative_to_data_home(my_string to, const char *name,
|
bool fn_format_relative_to_data_home(my_string to, const char *name,
|
||||||
const char *dir, const char *extension);
|
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 uint32 server_id;
|
||||||
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
|
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
|
||||||
|
@ -572,9 +576,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_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
|
||||||
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
|
LOCK_grant, LOCK_error_log, LOCK_delayed_insert,
|
||||||
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
||||||
LOCK_binlog_update, LOCK_slave, LOCK_server_id, LOCK_slave_list;
|
LOCK_server_id, LOCK_slave_list, LOCK_active_mi;
|
||||||
extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
|
extern pthread_cond_t COND_refresh,COND_thread_count;
|
||||||
COND_slave_stopped, COND_slave_start;
|
|
||||||
extern pthread_attr_t connection_attrib;
|
extern pthread_attr_t connection_attrib;
|
||||||
extern bool opt_endinfo, using_udf_functions, locked_in_memory,
|
extern bool opt_endinfo, using_udf_functions, locked_in_memory,
|
||||||
opt_using_transactions, use_temp_pool, mysql_embedded;
|
opt_using_transactions, use_temp_pool, mysql_embedded;
|
||||||
|
@ -611,6 +614,7 @@ extern struct show_var_st init_vars[];
|
||||||
extern struct show_var_st status_vars[];
|
extern struct show_var_st status_vars[];
|
||||||
extern enum db_type default_table_type;
|
extern enum db_type default_table_type;
|
||||||
extern enum enum_tx_isolation default_tx_isolation;
|
extern enum enum_tx_isolation default_tx_isolation;
|
||||||
|
extern char glob_hostname[FN_REFLEN];
|
||||||
|
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
extern pthread_t signal_thread;
|
extern pthread_t signal_thread;
|
||||||
|
|
|
@ -211,7 +211,7 @@ SHOW_COMP_OPTION have_openssl=SHOW_OPTION_NO;
|
||||||
SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES;
|
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 bool opt_do_pstack = 0;
|
||||||
static ulong opt_specialflag=SPECIAL_ENGLISH;
|
static ulong opt_specialflag=SPECIAL_ENGLISH;
|
||||||
static ulong back_log,connect_timeout,concurrency;
|
static ulong back_log,connect_timeout,concurrency;
|
||||||
|
@ -231,8 +231,6 @@ bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0,
|
||||||
volatile bool mqh_used = 0;
|
volatile bool mqh_used = 0;
|
||||||
FILE *bootstrap_file=0;
|
FILE *bootstrap_file=0;
|
||||||
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
|
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,
|
If sql_bin_update is true, SQL_LOG_UPDATE and SQL_LOG_BIN are kept in sync,
|
||||||
|
@ -244,7 +242,7 @@ static struct rand_struct sql_rand;
|
||||||
static int cleanup_done;
|
static int cleanup_done;
|
||||||
static char **defaults_argv,time_zone[30];
|
static char **defaults_argv,time_zone[30];
|
||||||
static const char *default_table_type_name;
|
static const char *default_table_type_name;
|
||||||
static char glob_hostname[FN_REFLEN];
|
char glob_hostname[FN_REFLEN];
|
||||||
|
|
||||||
#include "sslopt-vars.h"
|
#include "sslopt-vars.h"
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
|
@ -283,9 +281,11 @@ volatile ulong cached_thread_count=0;
|
||||||
|
|
||||||
// replication parameters, if master_host is not NULL, we are a slave
|
// replication parameters, if master_host is not NULL, we are a slave
|
||||||
my_string master_user = (char*) "test", master_password = 0, master_host=0,
|
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;
|
my_string report_user = 0, report_password = 0, report_host=0;
|
||||||
|
|
||||||
const char *localhost=LOCAL_HOST;
|
const char *localhost=LOCAL_HOST;
|
||||||
const char *delayed_user="DELAYED";
|
const char *delayed_user="DELAYED";
|
||||||
uint master_port = MYSQL_PORT, master_connect_retry = 60;
|
uint master_port = MYSQL_PORT, master_connect_retry = 60;
|
||||||
|
@ -315,7 +315,7 @@ ulong max_connections,max_insert_delayed_threads,max_used_connections,
|
||||||
ulong thread_id=1L,current_pid;
|
ulong thread_id=1L,current_pid;
|
||||||
ulong slow_launch_threads = 0;
|
ulong slow_launch_threads = 0;
|
||||||
ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
|
ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
|
||||||
|
|
||||||
char mysql_real_data_home[FN_REFLEN],
|
char mysql_real_data_home[FN_REFLEN],
|
||||||
language[LIBLEN],reg_ext[FN_EXTLEN],
|
language[LIBLEN],reg_ext[FN_EXTLEN],
|
||||||
default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
|
default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
|
||||||
|
@ -330,6 +330,7 @@ bool mysql_embedded=1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
|
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;
|
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
|
||||||
const char *first_keyword="first";
|
const char *first_keyword="first";
|
||||||
const char **errmesg; /* Error messages */
|
const char **errmesg; /* Error messages */
|
||||||
|
@ -365,8 +366,8 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
||||||
LOCK_error_log,
|
LOCK_error_log,
|
||||||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||||
LOCK_binlog_update, LOCK_slave, LOCK_server_id,
|
LOCK_server_id,
|
||||||
LOCK_user_conn, LOCK_slave_list;
|
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||||
|
|
||||||
Query_cache query_cache;
|
Query_cache query_cache;
|
||||||
|
|
||||||
|
@ -776,6 +777,7 @@ void clean_up(bool print_message)
|
||||||
my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
x_free(opt_bin_logname);
|
x_free(opt_bin_logname);
|
||||||
|
x_free(opt_relay_logname);
|
||||||
bitmap_free(&temp_pool);
|
bitmap_free(&temp_pool);
|
||||||
free_max_user_conn();
|
free_max_user_conn();
|
||||||
end_slave_list();
|
end_slave_list();
|
||||||
|
@ -1112,6 +1114,8 @@ void end_thread(THD *thd, bool put_in_cache)
|
||||||
DBUG_PRINT("info", ("sending a broadcast"))
|
DBUG_PRINT("info", ("sending a broadcast"))
|
||||||
|
|
||||||
/* Tell main we are ready */
|
/* 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_mutex_unlock(&LOCK_thread_count);
|
||||||
(void) pthread_cond_broadcast(&COND_thread_count);
|
(void) pthread_cond_broadcast(&COND_thread_count);
|
||||||
DBUG_PRINT("info", ("unlocked thread_count mutex"))
|
DBUG_PRINT("info", ("unlocked thread_count mutex"))
|
||||||
|
@ -1244,7 +1248,7 @@ static sig_handler handle_segfault(int sig)
|
||||||
fprintf(stderr, "Fatal signal %d while backtracing\n", sig);
|
fprintf(stderr, "Fatal signal %d while backtracing\n", sig);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
segfaulted = 1;
|
segfaulted = 1;
|
||||||
fprintf(stderr,"\
|
fprintf(stderr,"\
|
||||||
mysqld got signal %d;\n\
|
mysqld got signal %d;\n\
|
||||||
|
@ -1267,7 +1271,7 @@ key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\
|
||||||
bytes of memory\n", (keybuff_size + (my_default_record_cache_size +
|
bytes of memory\n", (keybuff_size + (my_default_record_cache_size +
|
||||||
sortbuff_size) * max_connections)/ 1024);
|
sortbuff_size) * max_connections)/ 1024);
|
||||||
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
|
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
|
||||||
|
|
||||||
#if defined(HAVE_LINUXTHREADS)
|
#if defined(HAVE_LINUXTHREADS)
|
||||||
if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
|
if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
|
||||||
{
|
{
|
||||||
|
@ -1283,6 +1287,7 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
|
||||||
#ifdef HAVE_STACKTRACE
|
#ifdef HAVE_STACKTRACE
|
||||||
if(!(test_flags & TEST_NO_STACKTRACE))
|
if(!(test_flags & TEST_NO_STACKTRACE))
|
||||||
{
|
{
|
||||||
|
fprintf(stderr,"thd=%p\n",thd);
|
||||||
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
|
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
|
||||||
thread_stack);
|
thread_stack);
|
||||||
}
|
}
|
||||||
|
@ -1612,9 +1617,10 @@ const char *load_default_groups[]= { "mysqld","server",0 };
|
||||||
char *libwrapName=NULL;
|
char *libwrapName=NULL;
|
||||||
#endif
|
#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,
|
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];
|
char tmp[FN_REFLEN];
|
||||||
if (!opt_name || !opt_name[0])
|
if (!opt_name || !opt_name[0])
|
||||||
|
@ -1638,7 +1644,8 @@ static void open_log(MYSQL_LOG *log, const char *hostname,
|
||||||
opt_name=tmp;
|
opt_name=tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log->open(opt_name,type);
|
log->open(opt_name,type,0,(read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
|
||||||
|
no_auto_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1734,19 +1741,15 @@ int main(int argc, char **argv)
|
||||||
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
|
(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_bytes_received,MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_timezone,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_server_id, MY_MUTEX_INIT_FAST);
|
||||||
(void) pthread_mutex_init(&LOCK_user_conn, 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_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_thread_count,NULL);
|
||||||
(void) pthread_cond_init(&COND_refresh,NULL);
|
(void) pthread_cond_init(&COND_refresh,NULL);
|
||||||
(void) pthread_cond_init(&COND_thread_cache,NULL);
|
(void) pthread_cond_init(&COND_thread_cache,NULL);
|
||||||
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
|
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
|
||||||
(void) pthread_cond_init(&COND_manager,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);
|
(void) pthread_cond_init(&COND_rpl_status, NULL);
|
||||||
init_signals();
|
init_signals();
|
||||||
|
|
||||||
|
@ -1846,20 +1849,9 @@ int main(int argc, char **argv)
|
||||||
LOG_NEW);
|
LOG_NEW);
|
||||||
using_update_log=1;
|
using_update_log=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
init_slave();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_bin_log && !server_id)
|
if (opt_bin_log && !server_id)
|
||||||
{
|
{
|
||||||
server_id= !master_host ? 1 : 2;
|
server_id= !master_host ? 1 : 2;
|
||||||
|
@ -2012,17 +2004,6 @@ The server will not act as a slave.");
|
||||||
sql_print_error("Warning: Can't create thread to manage maintenance");
|
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,"");
|
printf(ER(ER_READY),my_progname,server_version,"");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
@ -2693,7 +2674,8 @@ enum options {
|
||||||
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
|
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
|
||||||
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
|
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_DES_KEY_FILE, OPT_SLAVE_SKIP_ERRORS
|
OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
|
||||||
|
OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
@ -2819,6 +2801,8 @@ static struct option long_options[] = {
|
||||||
{"report-password", required_argument, 0, (int) OPT_REPORT_PASSWORD},
|
{"report-password", required_argument, 0, (int) OPT_REPORT_PASSWORD},
|
||||||
{"report-port", required_argument, 0, (int) OPT_REPORT_PORT},
|
{"report-port", required_argument, 0, (int) OPT_REPORT_PORT},
|
||||||
{"rpl-recovery-rank", required_argument, 0, (int) OPT_RPL_RECOVERY_RANK},
|
{"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-mode", no_argument, 0, (int) OPT_SAFE},
|
||||||
{"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
|
{"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
|
||||||
{"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE},
|
{"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE},
|
||||||
|
@ -2842,6 +2826,8 @@ static struct option long_options[] = {
|
||||||
{"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
|
{"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
|
||||||
{"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
|
{"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
|
||||||
{"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
|
{"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},
|
{"slave-load-tmpdir", required_argument, 0, (int) OPT_SLAVE_LOAD_TMPDIR},
|
||||||
{"slave-skip-errors", required_argument, 0,
|
{"slave-skip-errors", required_argument, 0,
|
||||||
(int) OPT_SLAVE_SKIP_ERRORS},
|
(int) OPT_SLAVE_SKIP_ERRORS},
|
||||||
|
@ -3265,8 +3251,8 @@ struct show_var_st status_vars[]= {
|
||||||
{"Select_range", (char*) &select_range_count, SHOW_LONG},
|
{"Select_range", (char*) &select_range_count, SHOW_LONG},
|
||||||
{"Select_range_check", (char*) &select_range_check_count, SHOW_LONG},
|
{"Select_range_check", (char*) &select_range_check_count, SHOW_LONG},
|
||||||
{"Select_scan", (char*) &select_scan_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_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_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
|
||||||
{"Slow_queries", (char*) &long_query_count, SHOW_LONG},
|
{"Slow_queries", (char*) &long_query_count, SHOW_LONG},
|
||||||
{"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG},
|
{"Sort_merge_passes", (char*) &filesort_merge_passes, SHOW_LONG},
|
||||||
|
@ -3678,6 +3664,14 @@ static void get_options(int argc,char **argv)
|
||||||
opt_update_log=1;
|
opt_update_log=1;
|
||||||
opt_update_logname=optarg; // Use hostname.# if null
|
opt_update_logname=optarg; // Use hostname.# if null
|
||||||
break;
|
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:
|
case (int) OPT_BIN_LOG_INDEX:
|
||||||
opt_binlog_index_name = optarg;
|
opt_binlog_index_name = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -3838,7 +3832,7 @@ static void get_options(int argc,char **argv)
|
||||||
opt_slow_log=1;
|
opt_slow_log=1;
|
||||||
opt_slow_logname=optarg;
|
opt_slow_logname=optarg;
|
||||||
break;
|
break;
|
||||||
case (int) OPT_SKIP_SLAVE_START:
|
case (int)OPT_SKIP_SLAVE_START:
|
||||||
opt_skip_slave_start = 1;
|
opt_skip_slave_start = 1;
|
||||||
break;
|
break;
|
||||||
case (int) OPT_SKIP_NEW:
|
case (int) OPT_SKIP_NEW:
|
||||||
|
@ -4143,6 +4137,9 @@ static void get_options(int argc,char **argv)
|
||||||
case OPT_MASTER_INFO_FILE:
|
case OPT_MASTER_INFO_FILE:
|
||||||
master_info_file=optarg;
|
master_info_file=optarg;
|
||||||
break;
|
break;
|
||||||
|
case OPT_RELAY_LOG_INFO_FILE:
|
||||||
|
relay_log_info_file=optarg;
|
||||||
|
break;
|
||||||
case OPT_MASTER_PORT:
|
case OPT_MASTER_PORT:
|
||||||
master_port= atoi(optarg);
|
master_port= atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -201,7 +201,7 @@ void end_slave_list()
|
||||||
|
|
||||||
static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
|
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;
|
uint32 target_server_id = mi->server_id;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -219,7 +219,7 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg)
|
||||||
return 1;
|
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;
|
delete ev;
|
||||||
mi->pos = my_b_tell(log);
|
mi->pos = my_b_tell(log);
|
||||||
|
@ -529,7 +529,7 @@ pthread_handler_decl(handle_failsafe_rpl,arg)
|
||||||
const char* msg = thd->enter_cond(&COND_rpl_status,
|
const char* msg = thd->enter_cond(&COND_rpl_status,
|
||||||
&LOCK_rpl_status, "Waiting for request");
|
&LOCK_rpl_status, "Waiting for request");
|
||||||
pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
|
pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
|
||||||
thd->proc_info="Processling request";
|
thd->proc_info="Processing request";
|
||||||
while (!break_req_chain)
|
while (!break_req_chain)
|
||||||
{
|
{
|
||||||
switch (rpl_status)
|
switch (rpl_status)
|
||||||
|
@ -632,10 +632,9 @@ static inline void cleanup_mysql_results(MYSQL_RES* db_res,
|
||||||
|
|
||||||
|
|
||||||
static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
|
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;
|
MYSQL_ROW row;
|
||||||
|
|
||||||
for( row = mc_mysql_fetch_row(table_res); row;
|
for( row = mc_mysql_fetch_row(table_res); row;
|
||||||
row = mc_mysql_fetch_row(table_res))
|
row = mc_mysql_fetch_row(table_res))
|
||||||
{
|
{
|
||||||
|
@ -651,11 +650,9 @@ static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db,
|
||||||
if (!tables_ok(thd, &table))
|
if (!tables_ok(thd, &table))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ((error = fetch_master_table(thd, db, table_name, mi, mysql)))
|
||||||
if ((error = fetch_nx_table(thd, db, table_name, &glob_mi, mysql)))
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,25 +663,26 @@ int load_master_data(THD* thd)
|
||||||
MYSQL_RES* master_status_res = 0;
|
MYSQL_RES* master_status_res = 0;
|
||||||
bool slave_was_running = 0;
|
bool slave_was_running = 0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
const char* errmsg=0;
|
||||||
|
int restart_thread_mask;
|
||||||
mc_mysql_init(&mysql);
|
mc_mysql_init(&mysql);
|
||||||
|
|
||||||
// we do not want anyone messing with the slave at all for the entire
|
// we do not want anyone messing with the slave at all for the entire
|
||||||
// duration of the data load;
|
// duration of the data load;
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
LOCK_ACTIVE_MI;
|
||||||
|
lock_slave_threads(active_mi);
|
||||||
// first, kill the slave
|
init_thread_mask(&restart_thread_mask,active_mi,0 /*not inverse*/);
|
||||||
if ((slave_was_running = slave_running))
|
if (restart_thread_mask &&
|
||||||
|
(error=terminate_slave_threads(active_mi,restart_thread_mask,
|
||||||
|
1 /*skip lock*/)))
|
||||||
{
|
{
|
||||||
abort_slave = 1;
|
send_error(&thd->net,error);
|
||||||
KICK_SLAVE;
|
unlock_slave_threads(active_mi);
|
||||||
thd->proc_info = "waiting for slave to die";
|
UNLOCK_ACTIVE_MI;
|
||||||
while (slave_running)
|
return 1;
|
||||||
pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connect_to_master(thd, &mysql, active_mi))
|
||||||
if (connect_to_master(thd, &mysql, &glob_mi))
|
|
||||||
{
|
{
|
||||||
net_printf(&thd->net, error = ER_CONNECT_TO_MASTER,
|
net_printf(&thd->net, error = ER_CONNECT_TO_MASTER,
|
||||||
mc_mysql_error(&mysql));
|
mc_mysql_error(&mysql));
|
||||||
|
@ -746,7 +744,7 @@ int load_master_data(THD* thd)
|
||||||
mess up and not exclude mysql database with the rules when
|
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
|
he actually means to - in this case, he is up for a surprise if
|
||||||
his priv tables get dropped and downloaded from master
|
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
|
by default, to allow inclusion of mysql database into load
|
||||||
data from master
|
data from master
|
||||||
*/
|
*/
|
||||||
|
@ -776,7 +774,7 @@ int load_master_data(THD* thd)
|
||||||
goto err;
|
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
|
// we do not report the error - fetch_db_tables handles it
|
||||||
cleanup_mysql_results(db_res, cur_table_res, table_res);
|
cleanup_mysql_results(db_res, cur_table_res, table_res);
|
||||||
|
@ -799,14 +797,15 @@ int load_master_data(THD* thd)
|
||||||
*/
|
*/
|
||||||
if (row[0] && row[1])
|
if (row[0] && row[1])
|
||||||
{
|
{
|
||||||
strmake(glob_mi.log_file_name, row[0], sizeof(glob_mi.log_file_name));
|
strmake(active_mi->master_log_name, row[0],
|
||||||
glob_mi.pos = atoi(row[1]); // atoi() is ok, since offset is <= 1GB
|
sizeof(active_mi->master_log_name));
|
||||||
if (glob_mi.pos < 4)
|
// atoi() is ok, since offset is <= 1GB
|
||||||
glob_mi.pos = 4; // don't hit the magic number
|
active_mi->master_log_pos = atoi(row[1]);
|
||||||
glob_mi.pending = 0;
|
if (active_mi->master_log_pos < 4)
|
||||||
flush_master_info(&glob_mi);
|
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);
|
mc_mysql_free_result(master_status_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,11 +816,35 @@ int load_master_data(THD* thd)
|
||||||
goto err;
|
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:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
unlock_slave_threads(active_mi);
|
||||||
if (slave_was_running)
|
UNLOCK_ACTIVE_MI;
|
||||||
start_slave(0, 0);
|
thd->proc_info = 0;
|
||||||
|
|
||||||
mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
|
mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init()
|
||||||
if (!error)
|
if (!error)
|
||||||
send_ok(&thd->net);
|
send_ok(&thd->net);
|
||||||
|
|
1772
sql/slave.cc
1772
sql/slave.cc
File diff suppressed because it is too large
Load diff
356
sql/slave.h
356
sql/slave.h
|
@ -2,70 +2,265 @@
|
||||||
#define SLAVE_H
|
#define SLAVE_H
|
||||||
|
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
|
#include "my_list.h"
|
||||||
#define SLAVE_NET_TIMEOUT 3600
|
#define SLAVE_NET_TIMEOUT 3600
|
||||||
#define MAX_SLAVE_ERROR 2000
|
#define MAX_SLAVE_ERRMSG 1024
|
||||||
|
|
||||||
|
/*
|
||||||
|
The replication is accomplished by starting two threads - I/O
|
||||||
|
thread, and SQL thread. I/O thread is associated with its
|
||||||
|
MASTER_INFO struct, so MASTER_INFO can be viewed as I/O thread
|
||||||
|
descriptor. SQL thread is associated with RELAY_LOG_INFO struct.
|
||||||
|
|
||||||
|
I/O thread reads maintains a connection to the master, and reads log
|
||||||
|
events from the master as they arrive, queueing them by writing them
|
||||||
|
out into the temporary slave binary log (relay log). The SQL thread,
|
||||||
|
in turn, reads the slave binary log executing each event.
|
||||||
|
|
||||||
|
Relay log is needed to be able to handle situations when there is a large
|
||||||
|
backlog of unprocessed events from the master (eg. one particular update
|
||||||
|
takes a day to finish), and to be able to restart the slave server without
|
||||||
|
having to re-read the master updates.
|
||||||
|
*/
|
||||||
|
|
||||||
extern ulong slave_net_timeout, master_retry_count;
|
extern ulong slave_net_timeout, master_retry_count;
|
||||||
extern MY_BITMAP slave_error_mask;
|
|
||||||
extern bool use_slave_mask;
|
|
||||||
extern char* slave_load_tmpdir;
|
extern char* slave_load_tmpdir;
|
||||||
|
extern my_string master_info_file,relay_log_info_file;
|
||||||
|
extern my_string opt_relay_logname, opt_relaylog_index_name;
|
||||||
|
extern bool opt_skip_slave_start;
|
||||||
|
struct st_master_info;
|
||||||
|
|
||||||
|
#define LOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
|
||||||
|
++active_mi_in_use; \
|
||||||
|
pthread_mutex_unlock(&LOCK_active_mi);}
|
||||||
|
|
||||||
|
#define UNLOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \
|
||||||
|
--active_mi_in_use; \
|
||||||
|
pthread_mutex_unlock(&LOCK_active_mi); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
st_relay_log_info contains information on the current relay log and
|
||||||
|
relay log offset, and master log name and log sequence corresponding to the
|
||||||
|
last update. Additionally, misc information specific to the SQL thread is
|
||||||
|
included.
|
||||||
|
|
||||||
|
st_relay_log_info is initialized from the slave.info file if such exists.
|
||||||
|
Otherwise, data members are intialized with defaults. The initialization is
|
||||||
|
done with init_relay_log_info() call.
|
||||||
|
|
||||||
|
The format of slave.info file:
|
||||||
|
|
||||||
|
relay_log_name
|
||||||
|
relay_log_pos
|
||||||
|
master_log_name
|
||||||
|
master_log_pos
|
||||||
|
|
||||||
|
To clean up, call end_relay_log_info()
|
||||||
|
*/
|
||||||
|
typedef struct st_relay_log_info
|
||||||
|
{
|
||||||
|
// info_fd - file descriptor of the info file. set only during
|
||||||
|
// initialization or clean up - safe to read anytime
|
||||||
|
// cur_log_fd - file descriptor of the current read relay log, protected by
|
||||||
|
// data_lock
|
||||||
|
File info_fd,cur_log_fd;
|
||||||
|
|
||||||
|
// IO_CACHE of the info file - set only during init or end, safe to read
|
||||||
|
// anytime
|
||||||
|
IO_CACHE info_file;
|
||||||
|
|
||||||
|
// name of current read relay log - protected by data_lock
|
||||||
|
char relay_log_name[FN_REFLEN];
|
||||||
|
|
||||||
|
// master log name corresponding to current read position - protected by
|
||||||
|
// data lock
|
||||||
|
char master_log_name[FN_REFLEN];
|
||||||
|
|
||||||
|
// original log position of last processed event - protected by data_lock
|
||||||
|
volatile uint32 master_log_pos;
|
||||||
|
|
||||||
|
// when we restart slave thread we need to have access to the previously
|
||||||
|
// created temporary tables. Modified only on init/end and by the SQL
|
||||||
|
// thread, read only by SQL thread, need no mutex
|
||||||
|
TABLE* save_temporary_tables;
|
||||||
|
|
||||||
|
// relay_log_pos - current offset in the relay log - protected by data_lock
|
||||||
|
// pending - in some cases we do not increment offset immediately after
|
||||||
|
// processing an event, because the following event needs to be processed
|
||||||
|
// atomically together with this one ( so far, there is only one type of
|
||||||
|
// such event - Intvar_event that sets auto_increment value). However, once
|
||||||
|
// both events have been processed, we need to increment by the cumulative
|
||||||
|
// offset. pending stored the extra offset to be added to the position.
|
||||||
|
ulonglong relay_log_pos,pending;
|
||||||
|
|
||||||
|
// standard lock acquistion order to avoid deadlocks:
|
||||||
|
// run_lock, data_lock, relay_log.LOCK_log,relay_log.LOCK_index
|
||||||
|
pthread_mutex_t data_lock,run_lock;
|
||||||
|
|
||||||
|
// start_cond is broadcast when SQL thread is started
|
||||||
|
// stop_cond - when stopped
|
||||||
|
// data_cond - when data protected by data_lock changes
|
||||||
|
pthread_cond_t start_cond,stop_cond,data_cond;
|
||||||
|
|
||||||
|
// if not set, the value of other members of the structure are undefined
|
||||||
|
bool inited;
|
||||||
|
|
||||||
|
// parent master info structure
|
||||||
|
struct st_master_info *mi;
|
||||||
|
|
||||||
|
// protected with internal locks
|
||||||
|
// must get data_lock when resetting the logs
|
||||||
|
MYSQL_LOG relay_log;
|
||||||
|
LOG_INFO linfo;
|
||||||
|
IO_CACHE cache_buf,*cur_log;
|
||||||
|
|
||||||
|
/* needed to deal properly with cur_log getting closed and re-opened with
|
||||||
|
a different log under our feet
|
||||||
|
*/
|
||||||
|
int cur_log_init_count;
|
||||||
|
|
||||||
|
volatile bool abort_slave, slave_running;
|
||||||
|
// needed for problems when slave stops and
|
||||||
|
// we want to restart it skipping one or more events in the master log that
|
||||||
|
// have caused errors, and have been manually applied by DBA already
|
||||||
|
volatile uint32 slave_skip_counter;
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
int events_till_abort;
|
||||||
|
#endif
|
||||||
|
int last_slave_errno;
|
||||||
|
char last_slave_error[MAX_SLAVE_ERRMSG];
|
||||||
|
THD* sql_thd;
|
||||||
|
bool log_pos_current;
|
||||||
|
|
||||||
|
st_relay_log_info():info_fd(-1),cur_log_fd(-1),inited(0),
|
||||||
|
cur_log_init_count(0),
|
||||||
|
log_pos_current(0)
|
||||||
|
{
|
||||||
|
relay_log_name[0] = master_log_name[0] = 0;
|
||||||
|
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
|
||||||
|
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
|
||||||
|
pthread_cond_init(&data_cond, NULL);
|
||||||
|
pthread_cond_init(&start_cond, NULL);
|
||||||
|
pthread_cond_init(&stop_cond, NULL);
|
||||||
|
}
|
||||||
|
~st_relay_log_info()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&run_lock);
|
||||||
|
pthread_mutex_destroy(&data_lock);
|
||||||
|
pthread_cond_destroy(&data_cond);
|
||||||
|
pthread_cond_destroy(&start_cond);
|
||||||
|
pthread_cond_destroy(&stop_cond);
|
||||||
|
}
|
||||||
|
inline void inc_pending(ulonglong val)
|
||||||
|
{
|
||||||
|
pending += val;
|
||||||
|
}
|
||||||
|
// TODO: this probably needs to be fixed
|
||||||
|
inline void inc_pos(ulonglong val, uint32 log_pos, bool skip_lock=0)
|
||||||
|
{
|
||||||
|
if (!skip_lock)
|
||||||
|
pthread_mutex_lock(&data_lock);
|
||||||
|
relay_log_pos += val+pending;
|
||||||
|
pending = 0;
|
||||||
|
if (log_pos)
|
||||||
|
master_log_pos = log_pos+val;
|
||||||
|
pthread_cond_broadcast(&data_cond);
|
||||||
|
if (!skip_lock)
|
||||||
|
pthread_mutex_unlock(&data_lock);
|
||||||
|
}
|
||||||
|
// thread safe read of position - not needed if we are in the slave thread,
|
||||||
|
// but required otherwise
|
||||||
|
inline void read_pos(ulonglong& var)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&data_lock);
|
||||||
|
var = relay_log_pos;
|
||||||
|
pthread_mutex_unlock(&data_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos);
|
||||||
|
} RELAY_LOG_INFO;
|
||||||
|
|
||||||
|
// repopen_relay_log() is called when we notice that the current "hot" log
|
||||||
|
// got rotated under our feet
|
||||||
|
IO_CACHE* reopen_relay_log(RELAY_LOG_INFO* rli, const char** errmsg);
|
||||||
|
Log_event* next_event(RELAY_LOG_INFO* rli);
|
||||||
|
|
||||||
|
/* st_master_info contains information about how to connect to a master,
|
||||||
|
current master log name, and current log offset, as well as misc
|
||||||
|
control variables
|
||||||
|
|
||||||
|
st_master_info is initialized once from the master.info file if such
|
||||||
|
exists. Otherwise, data members corresponding to master.info fields are
|
||||||
|
initialized with defaults specified by master-* options. The initialization
|
||||||
|
is done through init_master_info() call.
|
||||||
|
|
||||||
|
The format of master.info file:
|
||||||
|
|
||||||
|
log_name
|
||||||
|
log_pos
|
||||||
|
master_host
|
||||||
|
master_user
|
||||||
|
master_pass
|
||||||
|
master_port
|
||||||
|
master_connect_retry
|
||||||
|
|
||||||
|
To write out the contents of master.info file to disk ( needed every
|
||||||
|
time we read and queue data from the master ), a call to
|
||||||
|
flush_master_info() is required.
|
||||||
|
|
||||||
|
To clean up, call end_master_info()
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct st_master_info
|
typedef struct st_master_info
|
||||||
{
|
{
|
||||||
char log_file_name[FN_REFLEN];
|
char master_log_name[FN_REFLEN];
|
||||||
ulonglong pos,pending;
|
|
||||||
File fd; // we keep the file open, so we need to remember the file pointer
|
ulonglong master_log_pos;
|
||||||
|
File fd;
|
||||||
IO_CACHE file;
|
IO_CACHE file;
|
||||||
|
|
||||||
// the variables below are needed because we can change masters on the fly
|
// the variables below are needed because we can change masters on the fly
|
||||||
char host[HOSTNAME_LENGTH+1];
|
char host[HOSTNAME_LENGTH+1];
|
||||||
char user[USERNAME_LENGTH+1];
|
char user[USERNAME_LENGTH+1];
|
||||||
char password[HASH_PASSWORD_LENGTH+1];
|
char password[HASH_PASSWORD_LENGTH+1];
|
||||||
uint port;
|
uint port;
|
||||||
uint connect_retry;
|
uint connect_retry;
|
||||||
uint32 last_log_seq; // log sequence number of last processed event
|
pthread_mutex_t data_lock,run_lock;
|
||||||
pthread_mutex_t lock;
|
pthread_cond_t data_cond,start_cond,stop_cond;
|
||||||
pthread_cond_t cond;
|
|
||||||
bool inited;
|
bool inited;
|
||||||
bool old_format; /* master binlog is in 3.23 format */
|
bool old_format; /* master binlog is in 3.23 format */
|
||||||
|
RELAY_LOG_INFO rli;
|
||||||
st_master_info():pending(0),fd(-1),last_log_seq(0),inited(0),
|
#ifndef DBUG_OFF
|
||||||
old_format(0)
|
int events_till_abort;
|
||||||
|
#endif
|
||||||
|
volatile bool abort_slave, slave_running;
|
||||||
|
THD* io_thd;
|
||||||
|
|
||||||
|
st_master_info():fd(-1),inited(0),
|
||||||
|
old_format(0),io_thd(0)
|
||||||
{
|
{
|
||||||
host[0] = 0; user[0] = 0; password[0] = 0;
|
host[0] = 0; user[0] = 0; password[0] = 0;
|
||||||
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
|
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
|
||||||
pthread_cond_init(&cond, NULL);
|
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
|
||||||
|
pthread_cond_init(&data_cond, NULL);
|
||||||
|
pthread_cond_init(&start_cond, NULL);
|
||||||
|
pthread_cond_init(&stop_cond, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
~st_master_info()
|
~st_master_info()
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&lock);
|
pthread_mutex_destroy(&run_lock);
|
||||||
pthread_cond_destroy(&cond);
|
pthread_mutex_destroy(&data_lock);
|
||||||
}
|
pthread_cond_destroy(&data_cond);
|
||||||
inline void inc_pending(ulonglong val)
|
pthread_cond_destroy(&start_cond);
|
||||||
{
|
pthread_cond_destroy(&stop_cond);
|
||||||
pending += val;
|
|
||||||
}
|
|
||||||
inline void inc_pos(ulonglong val, uint32 log_seq)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&lock);
|
|
||||||
pos += val + pending;
|
|
||||||
pending = 0;
|
|
||||||
last_log_seq = log_seq;
|
|
||||||
pthread_cond_broadcast(&cond);
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
}
|
|
||||||
// thread safe read of position - not needed if we are in the slave thread,
|
|
||||||
// but required otherwise
|
|
||||||
inline void read_pos(ulonglong& var)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&lock);
|
|
||||||
var = pos;
|
|
||||||
pthread_mutex_unlock(&lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos);
|
|
||||||
} MASTER_INFO;
|
} MASTER_INFO;
|
||||||
|
|
||||||
|
int queue_event(MASTER_INFO* mi,const char* buf,uint event_len);
|
||||||
|
|
||||||
typedef struct st_table_rule_ent
|
typedef struct st_table_rule_ent
|
||||||
{
|
{
|
||||||
char* db;
|
char* db;
|
||||||
|
@ -77,22 +272,52 @@ typedef struct st_table_rule_ent
|
||||||
#define TABLE_RULE_ARR_SIZE 16
|
#define TABLE_RULE_ARR_SIZE 16
|
||||||
#define MAX_SLAVE_ERRMSG 1024
|
#define MAX_SLAVE_ERRMSG 1024
|
||||||
|
|
||||||
#define RPL_LOG_NAME (glob_mi.log_file_name[0] ? glob_mi.log_file_name :\
|
#define RPL_LOG_NAME (rli->master_log_name[0] ? rli->master_log_name :\
|
||||||
|
"FIRST")
|
||||||
|
#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
|
||||||
"FIRST")
|
"FIRST")
|
||||||
|
|
||||||
|
/* masks for start/stop operations on io and sql slave threads */
|
||||||
|
#define SLAVE_IO 1
|
||||||
|
#define SLAVE_SQL 2
|
||||||
|
#define SLAVE_FORCE_ALL 4 /* if this is set, if first gives an
|
||||||
|
error, second will be tried. Otherwise,
|
||||||
|
if first fails, we fail
|
||||||
|
*/
|
||||||
|
|
||||||
|
int init_slave();
|
||||||
int flush_master_info(MASTER_INFO* mi);
|
int flush_master_info(MASTER_INFO* mi);
|
||||||
|
int flush_relay_log_info(RELAY_LOG_INFO* rli);
|
||||||
int register_slave_on_master(MYSQL* mysql);
|
int register_slave_on_master(MYSQL* mysql);
|
||||||
|
int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
|
||||||
|
bool skip_lock = 0);
|
||||||
|
int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex,
|
||||||
|
pthread_mutex_t* cond_lock,
|
||||||
|
pthread_cond_t* term_cond,
|
||||||
|
volatile bool* slave_running);
|
||||||
|
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
|
||||||
|
MASTER_INFO* mi, const char* master_info_fname,
|
||||||
|
const char* slave_info_fname, int thread_mask);
|
||||||
|
/* cond_lock is usually same as start_lock. It is needed for the case when
|
||||||
|
start_lock is 0 which happens if start_slave_thread() is called already
|
||||||
|
inside the start_lock section, but at the same time we want a
|
||||||
|
pthread_cond_wait() on start_cond,start_lock
|
||||||
|
*/
|
||||||
|
int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
|
||||||
|
pthread_mutex_t *cond_lock,
|
||||||
|
pthread_cond_t* start_cond,
|
||||||
|
volatile bool* slave_running,
|
||||||
|
MASTER_INFO* mi);
|
||||||
|
|
||||||
int mysql_table_dump(THD* thd, const char* db,
|
int mysql_table_dump(THD* thd, const char* db,
|
||||||
const char* tbl_name, int fd = -1);
|
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, const char* db_name, const char* table_name,
|
int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
|
||||||
MASTER_INFO* mi, MYSQL* mysql);
|
MASTER_INFO* mi, MYSQL* mysql);
|
||||||
// retrieve non-exitent table from master
|
// retrieve non-exitent table from master
|
||||||
|
|
||||||
int show_master_info(THD* thd);
|
int show_master_info(THD* thd, MASTER_INFO* mi);
|
||||||
int show_binlog_info(THD* thd);
|
int show_binlog_info(THD* thd);
|
||||||
|
|
||||||
int tables_ok(THD* thd, TABLE_LIST* tables);
|
int tables_ok(THD* thd, TABLE_LIST* tables);
|
||||||
|
@ -107,30 +332,32 @@ int add_table_rule(HASH* h, const char* table_spec);
|
||||||
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
|
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
|
||||||
void init_table_rule_hash(HASH* h, bool* h_inited);
|
void init_table_rule_hash(HASH* h, bool* h_inited);
|
||||||
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
|
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
|
||||||
void init_slave_skip_errors(char* arg);
|
|
||||||
char* rewrite_db(char* db);
|
char* rewrite_db(char* db);
|
||||||
int check_expected_error(THD* thd, int error_code);
|
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
|
||||||
void skip_load_data_infile(NET* net);
|
void skip_load_data_infile(NET* net);
|
||||||
void slave_print_error(int err_code, const char* msg, ...);
|
void slave_print_error(RELAY_LOG_INFO* rli,int err_code, const char* msg, ...);
|
||||||
void end_slave(); // clean up
|
|
||||||
int init_master_info(MASTER_INFO* mi);
|
|
||||||
void end_master_info(MASTER_INFO* mi);
|
|
||||||
extern bool opt_log_slave_updates ;
|
|
||||||
pthread_handler_decl(handle_slave,arg);
|
|
||||||
extern bool volatile abort_loop, abort_slave, slave_running;
|
|
||||||
extern uint32 slave_skip_counter;
|
|
||||||
// needed for problems when slave stops and
|
|
||||||
// we want to restart it skipping one or more events in the master log that
|
|
||||||
// have caused errors, and have been manually applied by DBA already
|
|
||||||
|
|
||||||
extern int last_slave_errno;
|
void end_slave(); // clean up
|
||||||
#ifndef DBUG_OFF
|
int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
|
||||||
extern int events_till_abort;
|
const char* slave_info_fname);
|
||||||
#endif
|
void end_master_info(MASTER_INFO* mi);
|
||||||
extern char last_slave_error[MAX_SLAVE_ERRMSG];
|
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
|
||||||
extern pthread_t slave_real_id;
|
void end_relay_log_info(RELAY_LOG_INFO* rli);
|
||||||
extern THD* slave_thd;
|
void lock_slave_threads(MASTER_INFO* mi);
|
||||||
extern MASTER_INFO glob_mi;
|
void unlock_slave_threads(MASTER_INFO* mi);
|
||||||
|
void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse);
|
||||||
|
int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
|
||||||
|
bool need_data_lock, const char** errmsg);
|
||||||
|
|
||||||
|
int purge_relay_logs(RELAY_LOG_INFO* rli,bool just_reset,const char** errmsg);
|
||||||
|
|
||||||
|
extern bool opt_log_slave_updates ;
|
||||||
|
pthread_handler_decl(handle_slave_io,arg);
|
||||||
|
pthread_handler_decl(handle_slave_sql,arg);
|
||||||
|
extern bool volatile abort_loop;
|
||||||
|
extern MASTER_INFO main_mi, *active_mi; // active_mi for multi-master
|
||||||
|
extern volatile int active_mi_in_use;
|
||||||
|
extern LIST master_list;
|
||||||
extern HASH replicate_do_table, replicate_ignore_table;
|
extern HASH replicate_do_table, replicate_ignore_table;
|
||||||
extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
|
extern DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
|
||||||
extern bool do_table_inited, ignore_table_inited,
|
extern bool do_table_inited, ignore_table_inited,
|
||||||
|
@ -144,10 +371,13 @@ extern int disconnect_slave_event_count, abort_slave_event_count ;
|
||||||
// the master variables are defaults read from my.cnf or command line
|
// the master variables are defaults read from my.cnf or command line
|
||||||
extern uint master_port, master_connect_retry, report_port;
|
extern uint master_port, master_connect_retry, report_port;
|
||||||
extern my_string master_user, master_password, master_host,
|
extern my_string master_user, master_password, master_host,
|
||||||
master_info_file, report_user, report_host, report_password;
|
master_info_file, relay_log_info_file, report_user, report_host,
|
||||||
|
report_password;
|
||||||
|
|
||||||
extern I_List<i_string> replicate_do_db, replicate_ignore_db;
|
extern I_List<i_string> replicate_do_db, replicate_ignore_db;
|
||||||
extern I_List<i_string_pair> replicate_rewrite_db;
|
extern I_List<i_string_pair> replicate_rewrite_db;
|
||||||
extern I_List<THD> threads;
|
extern I_List<THD> threads;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,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;
|
||||||
log_seq = 0;
|
|
||||||
file_id = 0;
|
file_id = 0;
|
||||||
cond_count=0;
|
cond_count=0;
|
||||||
convert_set=0;
|
convert_set=0;
|
||||||
|
@ -119,6 +118,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
||||||
where="field list";
|
where="field list";
|
||||||
server_id = ::server_id;
|
server_id = ::server_id;
|
||||||
slave_net = 0;
|
slave_net = 0;
|
||||||
|
log_pos = 0;
|
||||||
server_status=SERVER_STATUS_AUTOCOMMIT;
|
server_status=SERVER_STATUS_AUTOCOMMIT;
|
||||||
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
|
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
|
||||||
options=thd_startup_options;
|
options=thd_startup_options;
|
||||||
|
@ -217,10 +217,11 @@ THD::~THD()
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void THD::prepare_to_die()
|
void THD::awake(bool prepare_to_die)
|
||||||
{
|
{
|
||||||
|
if (prepare_to_die)
|
||||||
|
killed = 1;
|
||||||
thr_alarm_kill(real_id);
|
thr_alarm_kill(real_id);
|
||||||
killed = 1;
|
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
close_active_vio();
|
close_active_vio();
|
||||||
#endif
|
#endif
|
||||||
|
@ -229,6 +230,10 @@ void THD::prepare_to_die()
|
||||||
pthread_mutex_lock(&mysys_var->mutex);
|
pthread_mutex_lock(&mysys_var->mutex);
|
||||||
if (!system_thread) // Don't abort locks
|
if (!system_thread) // Don't abort locks
|
||||||
mysys_var->abort=1;
|
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)
|
if (mysys_var->current_cond)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(mysys_var->current_mutex);
|
pthread_mutex_lock(mysys_var->current_mutex);
|
||||||
|
|
124
sql/sql_class.h
124
sql/sql_class.h
|
@ -21,6 +21,8 @@
|
||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: create log.h and move all the log header stuff there
|
||||||
|
|
||||||
class Query_log_event;
|
class Query_log_event;
|
||||||
class Load_log_event;
|
class Load_log_event;
|
||||||
class Slave_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_FATAL -7
|
||||||
#define LOG_INFO_IN_USE -8
|
#define LOG_INFO_IN_USE -8
|
||||||
|
|
||||||
|
struct st_relay_log_info;
|
||||||
|
|
||||||
typedef struct st_log_info
|
typedef struct st_log_info
|
||||||
{
|
{
|
||||||
char log_file_name[FN_REFLEN];
|
char log_file_name[FN_REFLEN];
|
||||||
|
@ -64,8 +68,6 @@ class MYSQL_LOG {
|
||||||
char time_buff[20],db[NAME_LEN+1];
|
char time_buff[20],db[NAME_LEN+1];
|
||||||
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
||||||
bool write_error,inited;
|
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
|
uint file_id; // current file sequence number for load data infile
|
||||||
// binary logging
|
// binary logging
|
||||||
bool no_rotate; // for binlog - if log name can never change
|
bool no_rotate; // for binlog - if log name can never change
|
||||||
|
@ -74,36 +76,52 @@ class MYSQL_LOG {
|
||||||
// purging
|
// purging
|
||||||
enum cache_type io_cache_type;
|
enum cache_type io_cache_type;
|
||||||
bool need_start_event;
|
bool need_start_event;
|
||||||
|
pthread_cond_t update_cond;
|
||||||
|
bool no_auto_events; // for relay binlog
|
||||||
friend class Log_event;
|
friend class Log_event;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MYSQL_LOG();
|
MYSQL_LOG();
|
||||||
~MYSQL_LOG();
|
~MYSQL_LOG();
|
||||||
pthread_mutex_t* get_log_lock() { return &LOCK_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_need_start_event() { need_start_event = 1; }
|
||||||
void set_index_file_name(const char* index_file_name = 0);
|
void set_index_file_name(const char* index_file_name = 0);
|
||||||
void init(enum_log_type log_type_arg,
|
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,
|
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);
|
void new_file(bool inside_mutex = 0);
|
||||||
bool open_index(int options);
|
bool open_index(int options);
|
||||||
void close_index();
|
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,
|
bool write(THD *thd, const char *query, uint query_length,
|
||||||
time_t query_start=0);
|
time_t query_start=0);
|
||||||
bool write(Log_event* event_info); // binary log write
|
bool write(Log_event* event_info); // binary log write
|
||||||
bool write(IO_CACHE *cache);
|
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);
|
int generate_new_name(char *new_name,const char *old_name);
|
||||||
void make_log_name(char* buf, const char* log_ident);
|
void make_log_name(char* buf, const char* log_ident);
|
||||||
bool is_active(const char* log_file_name);
|
bool is_active(const char* log_file_name);
|
||||||
int purge_logs(THD* thd, const char* to_log);
|
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
|
void close(bool exiting = 0); // if we are exiting, we also want to close the
|
||||||
// index file
|
// index file
|
||||||
|
|
||||||
// iterating through the log index file
|
// iterating through the log index file
|
||||||
int find_first_log(LOG_INFO* linfo, const char* log_name);
|
int find_first_log(LOG_INFO* linfo, const char* log_name,
|
||||||
int find_next_log(LOG_INFO* linfo);
|
bool need_mutex=1);
|
||||||
|
int find_next_log(LOG_INFO* linfo, bool need_mutex=1);
|
||||||
int get_current_log(LOG_INFO* linfo);
|
int get_current_log(LOG_INFO* linfo);
|
||||||
uint next_file_id();
|
uint next_file_id();
|
||||||
|
|
||||||
|
@ -228,33 +246,73 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
** every connection is handled by a thread with a THD
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
class delayed_insert;
|
class delayed_insert;
|
||||||
|
|
||||||
|
/* For each client connection we create a separate thread with THD serving as
|
||||||
|
a thread/connection descriptor */
|
||||||
|
|
||||||
class THD :public ilink {
|
class THD :public ilink {
|
||||||
public:
|
public:
|
||||||
NET net;
|
NET net; // client connection descriptor
|
||||||
LEX lex;
|
LEX lex; // parse tree descriptor
|
||||||
MEM_ROOT mem_root;
|
MEM_ROOT mem_root; // memory allocation pool
|
||||||
HASH user_vars;
|
HASH user_vars; // hash for user variables
|
||||||
String packet; /* Room for 1 row */
|
String packet; // dynamic string buffer used for network I/O
|
||||||
struct sockaddr_in remote;
|
struct sockaddr_in remote; // client socket address
|
||||||
struct rand_struct rand;
|
struct rand_struct rand; // used for authentication
|
||||||
char *query,*thread_stack;
|
|
||||||
char *host,*user,*priv_user,*db,*ip;
|
/* query points to the current query,
|
||||||
const char *proc_info, *host_or_ip;
|
thread_stack is a pointer to the stack frame of handle_one_connection(),
|
||||||
uint client_capabilities,sql_mode,max_packet_length;
|
which is called first in the thread for handling a client
|
||||||
uint master_access,db_access;
|
*/
|
||||||
TABLE *open_tables,*temporary_tables, *handler_tables;
|
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;
|
MYSQL_LOCK *lock,*locked_tables;
|
||||||
ULL *ull;
|
ULL *ull;
|
||||||
struct st_my_thread_var *mysys_var;
|
struct st_my_thread_var *mysys_var;
|
||||||
enum enum_server_command command;
|
enum enum_server_command command;
|
||||||
uint32 server_id;
|
uint32 server_id;
|
||||||
uint32 log_seq;
|
uint32 file_id; // for LOAD DATA INFILE
|
||||||
uint32 file_id; // for LOAD DATA INFILE
|
uint32 file_id; // for LOAD DATA INFILE
|
||||||
const char *where;
|
const char *where;
|
||||||
time_t start_time,time_after_lock,user_time;
|
time_t start_time,time_after_lock,user_time;
|
||||||
|
@ -312,6 +370,8 @@ public:
|
||||||
*/
|
*/
|
||||||
ulong slave_proxy_id;
|
ulong slave_proxy_id;
|
||||||
NET* slave_net; // network connection from slave -> m.
|
NET* slave_net; // network connection from slave -> m.
|
||||||
|
uint32 log_pos;
|
||||||
|
|
||||||
THD();
|
THD();
|
||||||
~THD();
|
~THD();
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
|
@ -333,14 +393,14 @@ public:
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&active_vio_lock);
|
pthread_mutex_lock(&active_vio_lock);
|
||||||
if(active_vio)
|
if(active_vio)
|
||||||
{
|
{
|
||||||
vio_close(active_vio);
|
vio_close(active_vio);
|
||||||
active_vio = 0;
|
active_vio = 0;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&active_vio_lock);
|
pthread_mutex_unlock(&active_vio_lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void prepare_to_die();
|
void awake(bool prepare_to_die);
|
||||||
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
|
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
|
||||||
const char* msg)
|
const char* msg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,7 +95,6 @@ typedef struct st_lex_master_info
|
||||||
{
|
{
|
||||||
char* host, *user, *password,*log_file_name;
|
char* host, *user, *password,*log_file_name;
|
||||||
uint port, connect_retry;
|
uint port, connect_retry;
|
||||||
ulong last_log_seq;
|
|
||||||
ulonglong pos;
|
ulonglong pos;
|
||||||
ulong server_id;
|
ulong server_id;
|
||||||
} LEX_MASTER_INFO;
|
} LEX_MASTER_INFO;
|
||||||
|
|
|
@ -1359,14 +1359,18 @@ mysql_execute_command(void)
|
||||||
{
|
{
|
||||||
if (check_access(thd, PROCESS_ACL, any_db))
|
if (check_access(thd, PROCESS_ACL, any_db))
|
||||||
goto error;
|
goto error;
|
||||||
res = change_master(thd);
|
LOCK_ACTIVE_MI;
|
||||||
|
res = change_master(thd,active_mi);
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_SHOW_SLAVE_STAT:
|
case SQLCOM_SHOW_SLAVE_STAT:
|
||||||
{
|
{
|
||||||
if (check_process_priv(thd))
|
if (check_process_priv(thd))
|
||||||
goto error;
|
goto error;
|
||||||
res = show_master_info(thd);
|
LOCK_ACTIVE_MI;
|
||||||
|
res = show_master_info(thd,active_mi);
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_SHOW_MASTER_STAT:
|
case SQLCOM_SHOW_MASTER_STAT:
|
||||||
|
@ -1376,15 +1380,15 @@ mysql_execute_command(void)
|
||||||
res = show_binlog_info(thd);
|
res = show_binlog_info(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
||||||
if (check_process_priv(thd))
|
if (check_process_priv(thd))
|
||||||
goto error;
|
goto error;
|
||||||
res = load_master_data(thd);
|
res = load_master_data(thd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_LOAD_MASTER_TABLE:
|
case SQLCOM_LOAD_MASTER_TABLE:
|
||||||
|
{
|
||||||
if (!tables->db)
|
if (!tables->db)
|
||||||
tables->db=thd->db;
|
tables->db=thd->db;
|
||||||
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
|
if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
|
||||||
|
@ -1404,12 +1408,16 @@ mysql_execute_command(void)
|
||||||
net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name);
|
net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
LOCK_ACTIVE_MI;
|
||||||
if (fetch_nx_table(thd, tables->db, tables->real_name, &glob_mi, 0))
|
// fetch_master_table will send the error to the client on failure
|
||||||
break; // fetch_nx_table did send the error to the client
|
if (!fetch_master_table(thd, tables->db, tables->real_name,
|
||||||
send_ok(&thd->net);
|
active_mi, 0))
|
||||||
|
{
|
||||||
|
send_ok(&thd->net);
|
||||||
|
}
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_CREATE_TABLE:
|
case SQLCOM_CREATE_TABLE:
|
||||||
if (!tables->db)
|
if (!tables->db)
|
||||||
tables->db=thd->db;
|
tables->db=thd->db;
|
||||||
|
@ -1509,12 +1517,19 @@ mysql_execute_command(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_SLAVE_START:
|
case SQLCOM_SLAVE_START:
|
||||||
start_slave(thd);
|
{
|
||||||
|
LOCK_ACTIVE_MI;
|
||||||
|
start_slave(thd,active_mi,1 /* net report*/);
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_SLAVE_STOP:
|
case SQLCOM_SLAVE_STOP:
|
||||||
stop_slave(thd);
|
{
|
||||||
|
LOCK_ACTIVE_MI;
|
||||||
|
stop_slave(thd,active_mi,1/* net report*/);
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_ALTER_TABLE:
|
case SQLCOM_ALTER_TABLE:
|
||||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
||||||
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||||
|
@ -3204,6 +3219,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
|
||||||
bool result=0;
|
bool result=0;
|
||||||
|
|
||||||
select_errors=0; /* Write if more errors */
|
select_errors=0; /* Write if more errors */
|
||||||
|
// TODO: figure out what's up with the commented out line below
|
||||||
// mysql_log.flush(); // Flush log
|
// mysql_log.flush(); // Flush log
|
||||||
if (options & REFRESH_GRANT)
|
if (options & REFRESH_GRANT)
|
||||||
{
|
{
|
||||||
|
@ -3244,16 +3260,22 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
|
||||||
if (options & REFRESH_THREADS)
|
if (options & REFRESH_THREADS)
|
||||||
flush_thread_cache();
|
flush_thread_cache();
|
||||||
if (options & REFRESH_MASTER)
|
if (options & REFRESH_MASTER)
|
||||||
reset_master();
|
if (reset_master(thd))
|
||||||
if (options & REFRESH_SLAVE)
|
result=1;
|
||||||
reset_slave();
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
if (options & REFRESH_DES_KEY_FILE)
|
if (options & REFRESH_DES_KEY_FILE)
|
||||||
{
|
{
|
||||||
if (des_key_file)
|
if (des_key_file)
|
||||||
result=load_des_key_file(des_key_file);
|
result=load_des_key_file(des_key_file);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (options & REFRESH_SLAVE)
|
||||||
|
{
|
||||||
|
LOCK_ACTIVE_MI;
|
||||||
|
if (reset_slave(active_mi))
|
||||||
|
result=1;
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3271,7 +3293,7 @@ void kill_one_thread(THD *thd, ulong id)
|
||||||
if ((thd->master_access & PROCESS_ACL) ||
|
if ((thd->master_access & PROCESS_ACL) ||
|
||||||
!strcmp(thd->user,tmp->user))
|
!strcmp(thd->user,tmp->user))
|
||||||
{
|
{
|
||||||
tmp->prepare_to_die();
|
tmp->awake(1 /*prepare to die*/);
|
||||||
error=0;
|
error=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
336
sql/sql_repl.cc
336
sql/sql_repl.cc
|
@ -23,9 +23,9 @@
|
||||||
#include "mini_client.h"
|
#include "mini_client.h"
|
||||||
#include <thr_alarm.h>
|
#include <thr_alarm.h>
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
extern const char* any_db;
|
extern const char* any_db;
|
||||||
extern pthread_handler_decl(handle_slave,arg);
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
int max_binlog_dump_events = 0; // unlimited
|
int max_binlog_dump_events = 0; // unlimited
|
||||||
|
@ -33,6 +33,26 @@ bool opt_sporadic_binlog_dump_fail = 0;
|
||||||
static int binlog_dump_count = 0;
|
static int binlog_dump_count = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int check_binlog_magic(IO_CACHE* log, const char** errmsg)
|
||||||
|
{
|
||||||
|
char magic[4];
|
||||||
|
DBUG_ASSERT(my_b_tell(log) == 0);
|
||||||
|
|
||||||
|
if (my_b_read(log, (byte*) magic, sizeof(magic)))
|
||||||
|
{
|
||||||
|
*errmsg = "I/O error reading the header from the binary log";
|
||||||
|
sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
|
||||||
|
log->error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
|
||||||
|
{
|
||||||
|
*errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
|
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
|
||||||
const char**errmsg)
|
const char**errmsg)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +66,10 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
|
||||||
int4store(header + SERVER_ID_OFFSET, server_id);
|
int4store(header + SERVER_ID_OFFSET, server_id);
|
||||||
int4store(header + EVENT_LEN_OFFSET, event_len);
|
int4store(header + EVENT_LEN_OFFSET, event_len);
|
||||||
int2store(header + FLAGS_OFFSET, 0);
|
int2store(header + FLAGS_OFFSET, 0);
|
||||||
int4store(header + LOG_SEQ_OFFSET, 0);
|
|
||||||
|
// TODO: check what problems this may cause and fix them
|
||||||
|
int4store(header + LOG_POS_OFFSET, 0);
|
||||||
|
|
||||||
packet->append(header, sizeof(header));
|
packet->append(header, sizeof(header));
|
||||||
/* We need to split the next statement because of problem with cxx */
|
/* We need to split the next statement because of problem with cxx */
|
||||||
int4store(buf,4); // tell slave to skip magic number
|
int4store(buf,4); // tell slave to skip magic number
|
||||||
|
@ -133,7 +156,6 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
|
||||||
const char **errmsg)
|
const char **errmsg)
|
||||||
{
|
{
|
||||||
File file;
|
File file;
|
||||||
char magic[4];
|
|
||||||
|
|
||||||
if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
|
if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
|
||||||
init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
|
init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
|
||||||
|
@ -142,19 +164,8 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
|
||||||
*errmsg = "Could not open log file"; // This will not be sent
|
*errmsg = "Could not open log file"; // This will not be sent
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (check_binlog_magic(log,errmsg))
|
||||||
if (my_b_read(log, (byte*) magic, sizeof(magic)))
|
|
||||||
{
|
|
||||||
*errmsg = "I/O error reading the header from the binary log";
|
|
||||||
sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
|
|
||||||
log->error);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
|
|
||||||
{
|
|
||||||
*errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
return file;
|
return file;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@ -366,7 +377,8 @@ impossible position";
|
||||||
packet->length(0);
|
packet->length(0);
|
||||||
packet->append("\0",1);
|
packet->append("\0",1);
|
||||||
}
|
}
|
||||||
|
// TODO: now that we are logging the offset, check to make sure
|
||||||
|
// the recorded offset and the actual match
|
||||||
if (error != LOG_READ_EOF)
|
if (error != LOG_READ_EOF)
|
||||||
{
|
{
|
||||||
switch(error) {
|
switch(error) {
|
||||||
|
@ -410,13 +422,6 @@ impossible position";
|
||||||
// to signal us
|
// to signal us
|
||||||
{
|
{
|
||||||
log.error=0;
|
log.error=0;
|
||||||
|
|
||||||
// tell the kill thread how to wake us up
|
|
||||||
thd->mysys_var->current_mutex = log_lock;
|
|
||||||
thd->mysys_var->current_cond = &COND_binlog_update;
|
|
||||||
const char* proc_info = thd->proc_info;
|
|
||||||
thd->proc_info = "Slave connection: waiting for binlog update";
|
|
||||||
|
|
||||||
bool read_packet = 0, fatal_error = 0;
|
bool read_packet = 0, fatal_error = 0;
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -431,32 +436,30 @@ impossible position";
|
||||||
// no one will update the log while we are reading
|
// no one will update the log while we are reading
|
||||||
// now, but we'll be quick and just read one record
|
// now, but we'll be quick and just read one record
|
||||||
pthread_mutex_lock(log_lock);
|
pthread_mutex_lock(log_lock);
|
||||||
switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0))
|
switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
pthread_mutex_unlock(log_lock);
|
||||||
read_packet = 1;
|
read_packet = 1;
|
||||||
// we read successfully, so we'll need to send it to the
|
// we read successfully, so we'll need to send it to the
|
||||||
// slave
|
// slave
|
||||||
break;
|
break;
|
||||||
case LOG_READ_EOF:
|
case LOG_READ_EOF:
|
||||||
DBUG_PRINT("wait",("waiting for data on binary log"));
|
DBUG_PRINT("wait",("waiting for data in binary log"));
|
||||||
|
// wait_for_update unlocks the log lock - needed to avoid race
|
||||||
if (!thd->killed)
|
if (!thd->killed)
|
||||||
pthread_cond_wait(&COND_binlog_update, log_lock);
|
mysql_bin_log.wait_for_update(thd);
|
||||||
|
else
|
||||||
|
pthread_mutex_unlock(log_lock);
|
||||||
DBUG_PRINT("wait",("binary log received update"));
|
DBUG_PRINT("wait",("binary log received update"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
pthread_mutex_unlock(log_lock);
|
||||||
fatal_error = 1;
|
fatal_error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(log_lock);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
|
||||||
thd->mysys_var->current_mutex= 0;
|
|
||||||
thd->mysys_var->current_cond= 0;
|
|
||||||
thd->proc_info= proc_info;
|
|
||||||
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
|
||||||
|
|
||||||
if (read_packet)
|
if (read_packet)
|
||||||
{
|
{
|
||||||
thd->proc_info = "sending update to slave";
|
thd->proc_info = "sending update to slave";
|
||||||
|
@ -548,39 +551,37 @@ impossible position";
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_slave(THD* thd , bool net_report)
|
int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
|
||||||
{
|
{
|
||||||
int slave_errno = 0;
|
int slave_errno = 0;
|
||||||
if (!thd) thd = current_thd;
|
if (!thd) thd = current_thd;
|
||||||
NET* net = &thd->net;
|
NET* net = &thd->net;
|
||||||
|
int thread_mask;
|
||||||
|
|
||||||
if (check_access(thd, PROCESS_ACL, any_db))
|
if (check_access(thd, PROCESS_ACL, any_db))
|
||||||
return 1;
|
return 1;
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
lock_slave_threads(mi); // this allows us to cleanly read slave_running
|
||||||
if (!slave_running)
|
init_thread_mask(&thread_mask,mi,1 /* inverse */);
|
||||||
|
if (thread_mask)
|
||||||
{
|
{
|
||||||
if (init_master_info(&glob_mi))
|
if (server_id_supplied && (!mi->inited || (mi->inited && *mi->host)))
|
||||||
slave_errno = ER_MASTER_INFO;
|
slave_errno = start_slave_threads(0 /*no mutex */,
|
||||||
else if (server_id_supplied && *glob_mi.host)
|
1 /* wait for start */,
|
||||||
{
|
mi,
|
||||||
pthread_t hThread;
|
master_info_file,relay_log_info_file,
|
||||||
if (pthread_create(&hThread, &connection_attrib, handle_slave, 0))
|
thread_mask);
|
||||||
{
|
|
||||||
slave_errno = ER_SLAVE_THREAD;
|
|
||||||
}
|
|
||||||
while (!slave_running) // slave might already be running by now
|
|
||||||
pthread_cond_wait(&COND_slave_start, &LOCK_slave);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
slave_errno = ER_BAD_SLAVE;
|
slave_errno = ER_BAD_SLAVE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
slave_errno = ER_SLAVE_MUST_STOP;
|
slave_errno = ER_SLAVE_MUST_STOP;
|
||||||
|
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
unlock_slave_threads(mi);
|
||||||
|
|
||||||
if (slave_errno)
|
if (slave_errno)
|
||||||
{
|
{
|
||||||
if (net_report) send_error(net, slave_errno);
|
if (net_report)
|
||||||
|
send_error(net, slave_errno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (net_report)
|
else if (net_report)
|
||||||
|
@ -589,8 +590,7 @@ int start_slave(THD* thd , bool net_report)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
|
||||||
int stop_slave(THD* thd, bool net_report )
|
|
||||||
{
|
{
|
||||||
int slave_errno = 0;
|
int slave_errno = 0;
|
||||||
if (!thd) thd = current_thd;
|
if (!thd) thd = current_thd;
|
||||||
|
@ -598,32 +598,14 @@ int stop_slave(THD* thd, bool net_report )
|
||||||
|
|
||||||
if (check_access(thd, PROCESS_ACL, any_db))
|
if (check_access(thd, PROCESS_ACL, any_db))
|
||||||
return 1;
|
return 1;
|
||||||
|
thd->proc_info = "Killing slave";
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
int thread_mask;
|
||||||
if (slave_running)
|
lock_slave_threads(mi);
|
||||||
{
|
init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
|
||||||
abort_slave = 1;
|
slave_errno = (thread_mask) ?
|
||||||
KICK_SLAVE;
|
terminate_slave_threads(mi,thread_mask,
|
||||||
// do not abort the slave in the middle of a query, so we do not set
|
1 /*skip lock */) : ER_SLAVE_NOT_RUNNING;
|
||||||
// thd->killed for the slave thread
|
unlock_slave_threads(mi);
|
||||||
thd->proc_info = "waiting for slave to die";
|
|
||||||
while (slave_running)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
There is a small chance that slave thread might miss the first
|
|
||||||
alarm. To protect againts it, resend the signal until it reacts
|
|
||||||
*/
|
|
||||||
struct timespec abstime;
|
|
||||||
set_timespec(abstime, 2);
|
|
||||||
pthread_cond_timedwait(&COND_slave_stopped, &LOCK_slave, &abstime);
|
|
||||||
if (slave_running)
|
|
||||||
KICK_SLAVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
slave_errno = ER_SLAVE_NOT_RUNNING;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
|
||||||
thd->proc_info = 0;
|
thd->proc_info = 0;
|
||||||
|
|
||||||
if (slave_errno)
|
if (slave_errno)
|
||||||
|
@ -638,31 +620,43 @@ int stop_slave(THD* thd, bool net_report )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reset_slave(MASTER_INFO* mi)
|
||||||
void reset_slave()
|
|
||||||
{
|
{
|
||||||
MY_STAT stat_area;
|
MY_STAT stat_area;
|
||||||
char fname[FN_REFLEN];
|
char fname[FN_REFLEN];
|
||||||
bool slave_was_running ;
|
int restart_thread_mask = 0,error=0;
|
||||||
|
const char* errmsg=0;
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
|
||||||
if ((slave_was_running = slave_running))
|
lock_slave_threads(mi);
|
||||||
{
|
init_thread_mask(&restart_thread_mask,mi,0 /* not inverse */);
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
if ((error=terminate_slave_threads(mi,restart_thread_mask,1 /*skip lock*/))
|
||||||
stop_slave(0,0);
|
|| (error=purge_relay_logs(&mi->rli,1 /*just reset*/,&errmsg)))
|
||||||
}
|
goto err;
|
||||||
else
|
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
end_master_info(mi);
|
||||||
|
|
||||||
end_master_info(&glob_mi);
|
|
||||||
fn_format(fname, master_info_file, mysql_data_home, "", 4+32);
|
fn_format(fname, master_info_file, mysql_data_home, "", 4+32);
|
||||||
if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
|
if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
|
||||||
return;
|
{
|
||||||
if (slave_was_running)
|
error=1;
|
||||||
start_slave(0,0);
|
goto err;
|
||||||
|
}
|
||||||
|
fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32);
|
||||||
|
if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME)))
|
||||||
|
{
|
||||||
|
error=1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (restart_thread_mask)
|
||||||
|
error=start_slave_threads(0 /* mutex not needed*/,
|
||||||
|
1 /* wait for start*/,
|
||||||
|
mi,master_info_file,relay_log_info_file,
|
||||||
|
restart_thread_mask);
|
||||||
|
// TODO: fix error messages so they get to the client
|
||||||
|
err:
|
||||||
|
unlock_slave_threads(mi);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void kill_zombie_dump_threads(uint32 slave_server_id)
|
void kill_zombie_dump_threads(uint32 slave_server_id)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_thread_count);
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
|
@ -681,119 +675,114 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
|
||||||
make safe_mutex complain and abort.
|
make safe_mutex complain and abort.
|
||||||
We just to do kill the thread ourselves.
|
We just to do kill the thread ourselves.
|
||||||
*/
|
*/
|
||||||
|
tmp->awake(1/*prepare to die*/);
|
||||||
thr_alarm_kill(tmp->real_id);
|
|
||||||
tmp->killed = 1;
|
|
||||||
tmp->mysys_var->abort = 1;
|
|
||||||
pthread_mutex_lock(&tmp->mysys_var->mutex);
|
|
||||||
if (tmp->mysys_var->current_cond)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(tmp->mysys_var->current_mutex);
|
|
||||||
pthread_cond_broadcast(tmp->mysys_var->current_cond);
|
|
||||||
pthread_mutex_unlock(tmp->mysys_var->current_mutex);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&tmp->mysys_var->mutex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_thread_count);
|
pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int change_master(THD* thd)
|
int change_master(THD* thd, MASTER_INFO* mi)
|
||||||
{
|
{
|
||||||
bool slave_was_running;
|
int error=0,restart_thread_mask;
|
||||||
|
const char* errmsg=0;
|
||||||
|
|
||||||
// kill slave thread
|
// kill slave thread
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
lock_slave_threads(mi);
|
||||||
if ((slave_was_running = slave_running))
|
init_thread_mask(&restart_thread_mask,mi,0 /*not inverse*/);
|
||||||
|
if (restart_thread_mask &&
|
||||||
|
(error=terminate_slave_threads(mi,
|
||||||
|
restart_thread_mask,
|
||||||
|
1 /*skip lock*/)))
|
||||||
{
|
{
|
||||||
abort_slave = 1;
|
send_error(&thd->net,error);
|
||||||
KICK_SLAVE;
|
unlock_slave_threads(mi);
|
||||||
thd->proc_info = "waiting for slave to die";
|
return 1;
|
||||||
while (slave_running)
|
|
||||||
pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
|
||||||
thd->proc_info = "changing master";
|
thd->proc_info = "changing master";
|
||||||
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
|
LEX_MASTER_INFO* lex_mi = &thd->lex.mi;
|
||||||
|
// TODO: see if needs re-write
|
||||||
if (init_master_info(&glob_mi))
|
if (init_master_info(mi,master_info_file,relay_log_info_file))
|
||||||
{
|
{
|
||||||
send_error(&thd->net, 0, "Could not initialize master info");
|
send_error(&thd->net, 0, "Could not initialize master info");
|
||||||
|
unlock_slave_threads(mi);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&glob_mi.lock);
|
pthread_mutex_lock(&mi->data_lock);
|
||||||
if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
|
if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
|
||||||
{
|
{
|
||||||
// if we change host or port, we must reset the postion
|
// if we change host or port, we must reset the postion
|
||||||
glob_mi.log_file_name[0] = 0;
|
mi->master_log_name[0] = 0;
|
||||||
glob_mi.pos = 4; // skip magic number
|
mi->master_log_pos = 4; // skip magic number
|
||||||
glob_mi.pending = 0;
|
mi->rli.pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex_mi->log_file_name)
|
if (lex_mi->log_file_name)
|
||||||
strmake(glob_mi.log_file_name, lex_mi->log_file_name,
|
strmake(mi->master_log_name, lex_mi->log_file_name,
|
||||||
sizeof(glob_mi.log_file_name));
|
sizeof(mi->master_log_name));
|
||||||
if (lex_mi->pos)
|
if (lex_mi->pos)
|
||||||
{
|
{
|
||||||
glob_mi.pos = lex_mi->pos;
|
mi->master_log_pos = lex_mi->pos;
|
||||||
glob_mi.pending = 0;
|
mi->rli.pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex_mi->host)
|
if (lex_mi->host)
|
||||||
strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host));
|
strmake(mi->host, lex_mi->host, sizeof(mi->host));
|
||||||
if (lex_mi->user)
|
if (lex_mi->user)
|
||||||
strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user));
|
strmake(mi->user, lex_mi->user, sizeof(mi->user));
|
||||||
if (lex_mi->password)
|
if (lex_mi->password)
|
||||||
strmake(glob_mi.password, lex_mi->password, sizeof(glob_mi.password));
|
strmake(mi->password, lex_mi->password, sizeof(mi->password));
|
||||||
if (lex_mi->port)
|
if (lex_mi->port)
|
||||||
glob_mi.port = lex_mi->port;
|
mi->port = lex_mi->port;
|
||||||
if (lex_mi->connect_retry)
|
if (lex_mi->connect_retry)
|
||||||
glob_mi.connect_retry = lex_mi->connect_retry;
|
mi->connect_retry = lex_mi->connect_retry;
|
||||||
|
|
||||||
|
flush_master_info(mi);
|
||||||
|
pthread_mutex_unlock(&mi->data_lock);
|
||||||
|
thd->proc_info="purging old relay logs";
|
||||||
|
if (purge_relay_logs(&mi->rli,0 /* not only reset, but also reinit*/,
|
||||||
|
&errmsg))
|
||||||
|
{
|
||||||
|
send_error(&thd->net, 0, "Failed purging old relay logs");
|
||||||
|
unlock_slave_threads(mi);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&mi->rli.data_lock);
|
||||||
|
mi->rli.master_log_pos = mi->master_log_pos;
|
||||||
|
strnmov(mi->rli.master_log_name,mi->master_log_name,
|
||||||
|
sizeof(mi->rli.master_log_name));
|
||||||
|
if (!mi->rli.master_log_name[0]) // uninitialized case
|
||||||
|
mi->rli.master_log_pos=0;
|
||||||
|
pthread_cond_broadcast(&mi->rli.data_cond);
|
||||||
|
pthread_mutex_unlock(&mi->rli.data_lock);
|
||||||
|
|
||||||
flush_master_info(&glob_mi);
|
|
||||||
pthread_mutex_unlock(&glob_mi.lock);
|
|
||||||
thd->proc_info = "starting slave";
|
thd->proc_info = "starting slave";
|
||||||
if (slave_was_running)
|
if (restart_thread_mask)
|
||||||
start_slave(0,0);
|
error=start_slave_threads(0 /* mutex not needed*/,
|
||||||
|
1 /* wait for start*/,
|
||||||
|
mi,master_info_file,relay_log_info_file,
|
||||||
|
restart_thread_mask);
|
||||||
|
err:
|
||||||
|
unlock_slave_threads(mi);
|
||||||
thd->proc_info = 0;
|
thd->proc_info = 0;
|
||||||
|
if (error)
|
||||||
send_ok(&thd->net);
|
send_error(&thd->net,error);
|
||||||
|
else
|
||||||
|
send_ok(&thd->net);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reset_master(THD* thd)
|
||||||
void reset_master()
|
|
||||||
{
|
{
|
||||||
if (!mysql_bin_log.is_open())
|
if (!mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG));
|
my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG));
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
return mysql_bin_log.reset_logs(thd);
|
||||||
LOG_INFO linfo;
|
|
||||||
pthread_mutex_t* log_lock = mysql_bin_log.get_log_lock();
|
|
||||||
pthread_mutex_lock(log_lock);
|
|
||||||
if (mysql_bin_log.find_first_log(&linfo, ""))
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock(log_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
my_delete(linfo.log_file_name, MYF(MY_WME));
|
|
||||||
if (mysql_bin_log.find_next_log(&linfo))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mysql_bin_log.close(1); // exiting close
|
|
||||||
my_delete(mysql_bin_log.get_index_fname(), MYF(MY_WME));
|
|
||||||
mysql_bin_log.set_need_start_event();
|
|
||||||
mysql_bin_log.open(opt_bin_logname,LOG_BIN);
|
|
||||||
pthread_mutex_unlock(log_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
|
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
|
||||||
const char* log_file_name2, ulonglong log_pos2)
|
const char* log_file_name2, ulonglong log_pos2)
|
||||||
{
|
{
|
||||||
|
@ -880,6 +869,7 @@ int show_binlog_events(THD* thd)
|
||||||
if (event_count < limit_end && log.error)
|
if (event_count < limit_end && log.error)
|
||||||
{
|
{
|
||||||
errmsg = "Wrong offset or I/O error";
|
errmsg = "Wrong offset or I/O error";
|
||||||
|
pthread_mutex_unlock(mysql_bin_log.get_log_lock());
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,11 +1002,11 @@ err:
|
||||||
int log_loaded_block(IO_CACHE* file)
|
int log_loaded_block(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
LOAD_FILE_INFO* lf_info;
|
LOAD_FILE_INFO* lf_info;
|
||||||
ulong block_len ;
|
uint block_len ;
|
||||||
|
|
||||||
/* file->request_pos contains position where we started last read */
|
/* file->request_pos contains position where we started last read */
|
||||||
byte *buffer = file->request_pos;
|
char* buffer = (char*) file->request_pos;
|
||||||
if (!(block_len = (ulong) (file->read_end - buffer)))
|
if (!(block_len = file->read_end - buffer))
|
||||||
return 0;
|
return 0;
|
||||||
lf_info = (LOAD_FILE_INFO*)file->arg;
|
lf_info = (LOAD_FILE_INFO*)file->arg;
|
||||||
if (lf_info->last_pos_in_file != HA_POS_ERROR &&
|
if (lf_info->last_pos_in_file != HA_POS_ERROR &&
|
||||||
|
@ -1025,14 +1015,14 @@ int log_loaded_block(IO_CACHE* file)
|
||||||
lf_info->last_pos_in_file = file->pos_in_file;
|
lf_info->last_pos_in_file = file->pos_in_file;
|
||||||
if (lf_info->wrote_create_file)
|
if (lf_info->wrote_create_file)
|
||||||
{
|
{
|
||||||
Append_block_log_event a(lf_info->thd, (char*) buffer, block_len);
|
Append_block_log_event a(lf_info->thd, buffer, block_len);
|
||||||
mysql_bin_log.write(&a);
|
mysql_bin_log.write(&a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
|
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
|
||||||
lf_info->table_name, *lf_info->fields,
|
lf_info->table_name, *lf_info->fields,
|
||||||
lf_info->handle_dup, (char*) buffer,
|
lf_info->handle_dup, buffer,
|
||||||
block_len);
|
block_len);
|
||||||
mysql_bin_log.write(&c);
|
mysql_bin_log.write(&c);
|
||||||
lf_info->wrote_create_file = 1;
|
lf_info->wrote_create_file = 1;
|
||||||
|
@ -1040,3 +1030,5 @@ int log_loaded_block(IO_CACHE* file)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,30 +26,26 @@ extern int max_binlog_dump_events;
|
||||||
extern bool opt_sporadic_binlog_dump_fail;
|
extern bool opt_sporadic_binlog_dump_fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#define KICK_SLAVE(thd) thd->awake(0 /* do not prepare to die*/);
|
||||||
#define KICK_SLAVE { slave_thd->close_active_vio(); \
|
|
||||||
thr_alarm_kill(slave_real_id); }
|
|
||||||
#else
|
|
||||||
#define KICK_SLAVE thr_alarm_kill(slave_real_id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
File open_binlog(IO_CACHE *log, const char *log_file_name,
|
File open_binlog(IO_CACHE *log, const char *log_file_name,
|
||||||
const char **errmsg);
|
const char **errmsg);
|
||||||
|
|
||||||
int start_slave(THD* thd = 0, bool net_report = 1);
|
int start_slave(THD* thd, MASTER_INFO* mi, bool net_report);
|
||||||
int stop_slave(THD* thd = 0, bool net_report = 1);
|
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report);
|
||||||
int change_master(THD* thd);
|
int change_master(THD* thd, MASTER_INFO* mi);
|
||||||
int show_binlog_events(THD* thd);
|
int show_binlog_events(THD* thd);
|
||||||
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
|
int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
|
||||||
const char* log_file_name2, ulonglong log_pos2);
|
const char* log_file_name2, ulonglong log_pos2);
|
||||||
void reset_slave();
|
int reset_slave(MASTER_INFO* mi);
|
||||||
void reset_master();
|
int reset_master(THD* thd);
|
||||||
int purge_master_logs(THD* thd, const char* to_log);
|
int purge_master_logs(THD* thd, const char* to_log);
|
||||||
bool log_in_use(const char* log_name);
|
bool log_in_use(const char* log_name);
|
||||||
void adjust_linfo_offsets(my_off_t purge_offset);
|
void adjust_linfo_offsets(my_off_t purge_offset);
|
||||||
int show_binlogs(THD* thd);
|
int show_binlogs(THD* thd);
|
||||||
extern int init_master_info(MASTER_INFO* mi);
|
extern int init_master_info(MASTER_INFO* mi);
|
||||||
void kill_zombie_dump_threads(uint32 slave_server_id);
|
void kill_zombie_dump_threads(uint32 slave_server_id);
|
||||||
|
int check_binlog_magic(IO_CACHE* log, const char** errmsg);
|
||||||
|
|
||||||
typedef struct st_load_file_info
|
typedef struct st_load_file_info
|
||||||
{
|
{
|
||||||
|
|
|
@ -1177,6 +1177,15 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
|
||||||
case SHOW_RPL_STATUS:
|
case SHOW_RPL_STATUS:
|
||||||
net_store_data(&packet2, rpl_status_type[(int)rpl_status]);
|
net_store_data(&packet2, rpl_status_type[(int)rpl_status]);
|
||||||
break;
|
break;
|
||||||
|
case SHOW_SLAVE_RUNNING:
|
||||||
|
{
|
||||||
|
LOCK_ACTIVE_MI;
|
||||||
|
net_store_data(&packet2, (active_mi->slave_running &&
|
||||||
|
active_mi->rli.slave_running)
|
||||||
|
? "ON" : "OFF");
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SHOW_OPENTABLES:
|
case SHOW_OPENTABLES:
|
||||||
net_store_data(&packet2,(uint32) cached_tables());
|
net_store_data(&packet2,(uint32) cached_tables());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2530,17 +2530,15 @@ show_param:
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
|
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
|
||||||
TEXT_STRING AND MASTER_LOG_POS_SYM EQ ulonglong_num AND
|
TEXT_STRING AND MASTER_LOG_POS_SYM EQ ulonglong_num
|
||||||
MASTER_LOG_SEQ_SYM EQ ULONG_NUM AND MASTER_SERVER_ID_SYM EQ
|
AND MASTER_SERVER_ID_SYM EQ
|
||||||
ULONG_NUM
|
ULONG_NUM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
|
||||||
lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
|
Lex->mi.log_file_name = $8.str;
|
||||||
lex->mi.log_file_name = $8.str;
|
Lex->mi.pos = $12;
|
||||||
lex->mi.pos = $12;
|
Lex->mi.server_id = $16;
|
||||||
lex->mi.last_log_seq = $16;
|
}
|
||||||
lex->mi.server_id = $20;
|
|
||||||
}
|
|
||||||
| MASTER_SYM LOGS_SYM
|
| MASTER_SYM LOGS_SYM
|
||||||
{
|
{
|
||||||
Lex->sql_command = SQLCOM_SHOW_BINLOGS;
|
Lex->sql_command = SQLCOM_SHOW_BINLOGS;
|
||||||
|
@ -3176,12 +3174,18 @@ option_value:
|
||||||
}
|
}
|
||||||
| SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
|
| SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
LOCK_ACTIVE_MI;
|
||||||
if (slave_running)
|
pthread_mutex_lock(&active_mi->rli.run_lock);
|
||||||
|
if (active_mi->rli.slave_running)
|
||||||
send_error(¤t_thd->net, ER_SLAVE_MUST_STOP);
|
send_error(¤t_thd->net, ER_SLAVE_MUST_STOP);
|
||||||
else
|
else
|
||||||
slave_skip_counter = $3;
|
{
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
pthread_mutex_lock(&active_mi->rli.data_lock);
|
||||||
|
active_mi->rli.slave_skip_counter = $3;
|
||||||
|
pthread_mutex_unlock(&active_mi->rli.data_lock);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&active_mi->rli.run_lock);
|
||||||
|
UNLOCK_ACTIVE_MI;
|
||||||
}
|
}
|
||||||
| ident equal DEFAULT
|
| ident equal DEFAULT
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,7 +123,7 @@ terribly wrong...\n");
|
||||||
}
|
}
|
||||||
#endif /* __alpha__ */
|
#endif /* __alpha__ */
|
||||||
|
|
||||||
if (!stack_bottom)
|
if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
|
||||||
{
|
{
|
||||||
ulong tmp= min(0x10000,thread_stack);
|
ulong tmp= min(0x10000,thread_stack);
|
||||||
/* Assume that the stack starts at the previous even 65K */
|
/* Assume that the stack starts at the previous even 65K */
|
||||||
|
|
|
@ -140,7 +140,7 @@ enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
|
||||||
,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL
|
,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL
|
||||||
,SHOW_SSL_GET_CIPHER_LIST
|
,SHOW_SSL_GET_CIPHER_LIST
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
,SHOW_RPL_STATUS
|
,SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
|
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
|
||||||
|
|
9
support-files/build-tags
Executable file
9
support-files/build-tags
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
rm -f TAGS
|
||||||
|
filter='\.cc$\|\.c$\|\.h$\|\.yy$'
|
||||||
|
files=`bk -r sfiles -gU | grep $filter `
|
||||||
|
for f in $files ;
|
||||||
|
do
|
||||||
|
etags -o TAGS --append $f
|
||||||
|
done
|
Loading…
Add table
Reference in a new issue