diff options
author | unknown <monty@tik.mysql.fi> | 2001-07-10 15:53:08 +0300 |
---|---|---|
committer | unknown <monty@tik.mysql.fi> | 2001-07-10 15:53:08 +0300 |
commit | 9914a0c8471b9ee1f041b13c11211fe277cfcd91 (patch) | |
tree | 6c8e56d350fb233a41c963d85544d41c0151c8ec | |
parent | 0b083a0d766bbc25e2b1264dd41a421703ac581f (diff) | |
download | mariadb-git-9914a0c8471b9ee1f041b13c11211fe277cfcd91.tar.gz |
Redefinition of myisam_bulk_insert_tree_size
Removed new error message
Fixed test case for varbinary
Threads are again killable in "merge_buffers"
Cleanup of sql_repl.cc
SHOW OPEN TABLES now works when no tables are opened
Docs/manual.texi:
Redefinition of myisam_bulk_insert_tree_size
client/insert_test.c:
Changed to use mysql_real_connect()
include/mysql.h:
Moved things in mysql_options to optimize these for 64 bit processors
include/mysqld_error.h:
Removed new error message
myisam/mi_write.c:
Use myisam_bulk_insert_tree_size per table instead of per index
mysql-test/t/varbinary.test:
Fixed test case for varbinary
mysys/tree.c:
Fixed missing if
sql/filesort.cc:
Threads are again killable in "merge_buffers"
sql/log_event.h:
cleanup
sql/share/czech/errmsg.txt:
Removed new error message
sql/share/danish/errmsg.txt:
Removed new error message
sql/share/dutch/errmsg.txt:
Removed new error message
sql/share/english/errmsg.txt:
Removed new error message
sql/share/estonian/errmsg.txt:
Removed new error message
sql/share/french/errmsg.txt:
Removed new error message
sql/share/german/errmsg.txt:
Removed new error message
sql/share/greek/errmsg.txt:
Removed new error message
sql/share/hungarian/errmsg.txt:
Removed new error message
sql/share/italian/errmsg.txt:
Removed new error message
sql/share/japanese/errmsg.txt:
Removed new error message
sql/share/korean/errmsg.txt:
Removed new error message
sql/share/norwegian-ny/errmsg.txt:
Removed new error message
sql/share/norwegian/errmsg.txt:
Removed new error message
sql/share/polish/errmsg.txt:
Removed new error message
sql/share/portuguese/errmsg.txt:
Removed new error message
sql/share/romanian/errmsg.txt:
Removed new error message
sql/share/russian/errmsg.txt:
Removed new error message
sql/share/slovak/errmsg.txt:
Removed new error message
sql/share/spanish/errmsg.txt:
Removed new error message
sql/share/swedish/errmsg.txt:
Removed new error message
sql/sql_class.h:
Cleanup
sql/sql_delete.cc:
Cleanup
sql/sql_repl.cc:
Cleanup
sql/sql_show.cc:
SHOW OPEN TABLES now works when no tables are opened
sql/sql_sort.h:
Threads are again killable in "merge_buffers"
sql/uniques.cc:
Threads are again killable in "merge_buffers"
36 files changed, 543 insertions, 580 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index 0213446f044..9d5df7e365a 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -22266,11 +22266,11 @@ The buffer that is allocated when sorting the index when doing a @code{ALTER TABLE}. @item @code{myisam_bulk_insert_tree_size} -@strong{MySQL} uses special tree-like cache to make bulk inserts (that is, +@code{MyISAM} uses special tree-like cache to make bulk inserts (that is, @code{INSERT ... SELECT}, @code{INSERT ... VALUES (...), (...), ...}, and @code{LOAD DATA INFILE}) faster. This variable limits -the size of the cache tree in bytes @strong{per thread, per index}. +the size of the cache tree in bytes @strong{per thread, per table}. Default value is 8 MB. @item @code{myisam_max_extra_sort_file_size}. @@ -23960,7 +23960,7 @@ The following options to @code{mysqld} can be used to change the behavior of @item @code{--delay-key-write-for-all-tables} @tab Don't flush key buffers between writes for any MyISAM table @item @code{-O myisam_max_extra_sort_file_size=#} @tab Used to help @strong{MySQL} to decide when to use the slow but safe key cache index create method. @strong{NOTE} that this parameter is given in megabytes! @item @code{-O myisam_max_sort_file_size=#} @tab Don't use the fast sort index method to created index if the temporary file would get bigger than this. @strong{NOTE} that this paramter is given in megabytes! -@item @code{-O myisam_bulk_insert_tree_size=#} @tab Size of tree cache used in bulk insert optimization. @strong{NOTE} that this is a limit @strong{per index}! +@item @code{-O myisam_bulk_insert_tree_size=#} @tab Size of tree cache used in bulk insert optimization. @strong{NOTE} that this is the total size used for all index in one table. @end multitable The automatic recovery is activated if you start @code{mysqld} with diff --git a/client/insert_test.c b/client/insert_test.c index 640935d63b2..82609f68e4e 100644 --- a/client/insert_test.c +++ b/client/insert_test.c @@ -34,19 +34,13 @@ int main(int argc, char **argv) exit(1); } - if (!(sock = mysql_connect(&mysql,NULL,0,0))) + if (!(sock = mysql_real_connect(&mysql,NULL,NULL,NULL,argv[1],0,NULL,0))) { fprintf(stderr,"Couldn't connect to engine!\n%s\n",mysql_error(&mysql)); perror(""); exit(1); } - if (mysql_select_db(sock,argv[1])) - { - fprintf(stderr,"Couldn't select database %s!\n%s\n",argv[1], - mysql_error(sock)); - } - num = atoi(argv[2]); count = 0; while (count < num) diff --git a/include/mysql.h b/include/mysql.h index 4ce7e80bcb9..b4a7f977cd5 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -126,24 +126,30 @@ typedef struct st_mysql_data { struct st_mysql_options { unsigned int connect_timeout,client_flag; - my_bool compress,named_pipe; - my_bool rpl_probe; /* on connect, find out the replication - role of the server, and establish connections - to all the peers */ - my_bool rpl_parse; /* each call to mysql_real_query() will parse - it to tell if it is a read or a write, and - direct it to the slave or the master */ - my_bool no_master_reads; /* if set, never read from - a master,only from slave, when doing - a read that is replication-aware */ unsigned int port; char *host,*init_command,*user,*password,*unix_socket,*db; char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name; - my_bool use_ssl; /* if to use SSL or not */ char *ssl_key; /* PEM key file */ char *ssl_cert; /* PEM cert file */ char *ssl_ca; /* PEM CA file */ char *ssl_capath; /* PEM directory of CA-s? */ + my_bool use_ssl; /* if to use SSL or not */ + my_bool compress,named_pipe; + /* + on connect, find out the replication role of the server, and + establish connections to all the peers + */ + my_bool rpl_probe; + /* + each call to mysql_real_query() will parse it to tell if it is a read + or a write, and direct it to the slave or the master + */ + my_bool rpl_parse; + /* + if set, never read from a master,only from slave, when doing + a read that is replication-aware + */ + my_bool no_master_reads; }; enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, @@ -154,12 +160,13 @@ enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT}; -/* there are three types of queries - the ones that have to go to - the master, the ones that go to a slave, and the adminstrative - type which must happen on the pivot connectioin +/* + There are three types of queries - the ones that have to go to + the master, the ones that go to a slave, and the adminstrative + type which must happen on the pivot connectioin */ enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, - MYSQL_RPL_ADMIN }; + MYSQL_RPL_ADMIN }; typedef struct st_mysql { @@ -191,15 +198,13 @@ typedef struct st_mysql { struct st_mysql* master, *next_slave; struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ - struct st_mysql* last_used_con; /* needed for send/read/store/use - result to work - correctly with replication - */ - my_bool rpl_pivot; /* set if this is the original connection, - not a master or a slave we have added though - mysql_rpl_probe() or mysql_set_master()/ - mysql_add_slave() - */ + /* needed for send/read/store/use result to work correctly with replication */ + struct st_mysql* last_used_con; + /* + Set if this is the original connection, not a master or a slave we have + added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() + */ + my_bool rpl_pivot; } MYSQL; @@ -246,11 +251,8 @@ int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, char * STDCALL mysql_ssl_cipher(MYSQL *mysql); int STDCALL mysql_ssl_clear(MYSQL *mysql); #endif /* HAVE_OPENSSL */ -MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, - const char *user, const char *passwd); my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db); -#if MYSQL_VERSION_ID >= 32200 MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, @@ -258,14 +260,6 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, unsigned int port, const char *unix_socket, unsigned int clientflag); -#else -MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, - const char *user, - const char *passwd, - unsigned int port, - const char *unix_socket, - unsigned int clientflag); -#endif void STDCALL mysql_close(MYSQL *sock); int STDCALL mysql_select_db(MYSQL *mysql, const char *db); int STDCALL mysql_query(MYSQL *mysql, const char *q); @@ -285,8 +279,10 @@ int STDCALL mysql_slave_query(MYSQL *mysql, const char *q, int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, unsigned int length); -/* enable/disable parsing of all queries to decide - if they go on master or slave */ +/* + enable/disable parsing of all queries to decide if they go on master or + slave +*/ void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); /* get the value of the parse flag */ @@ -305,17 +301,14 @@ int STDCALL mysql_rpl_probe(MYSQL* mysql); /* set the master, close/free the old one, if it is not a pivot */ int STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); + unsigned int port, + const char* user, + const char* passwd); int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); - + unsigned int port, + const char* user, + const char* passwd); -int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); -int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); int STDCALL mysql_shutdown(MYSQL *mysql); int STDCALL mysql_dump_debug_info(MYSQL *mysql); int STDCALL mysql_refresh(MYSQL *mysql, @@ -364,9 +357,15 @@ char * STDCALL mysql_odbc_escape_string(MYSQL *mysql, void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); - #define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) +#ifndef USE_OLD_FUNCTIONS +MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd); +int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); +int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); +#endif + /* new api functions */ #define HAVE_MYSQL_REAL_CONNECT diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 5777c8c7bef..b858ae89ef1 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -212,6 +212,5 @@ #define ER_CREATE_DB_WITH_READ_LOCK 1209 #define ER_CONNECT_TO_MASTER 1210 #define ER_QUERY_ON_MASTER 1211 -#define ER_SHOW_BINLOG_EVENTS 1212 -#define ER_SHOW_NEW_MASTER 1213 -#define ER_ERROR_MESSAGES 214 +#define ER_ERROR_WHEN_EXECUTING_COMMAND 1212 +#define ER_ERROR_MESSAGES 213 diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 5624e0ac44c..085490649a8 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -770,8 +770,9 @@ int _mi_init_bulk_insert(MI_INFO *info) if (info->bulk_insert) return 0; - info->bulk_insert=(TREE *)my_malloc( - (sizeof(TREE)+sizeof(bulk_insert_param))*share->base.keys, MYF(0)); + info->bulk_insert=(TREE *) + my_malloc((sizeof(TREE)+sizeof(bulk_insert_param))*share->base.keys, + MYF(0)); if (!info->bulk_insert) return HA_ERR_OUT_OF_MEM; @@ -785,9 +786,10 @@ int _mi_init_bulk_insert(MI_INFO *info) if (!(key->flag & HA_NOSAME) && share->base.auto_key != i+1 && test(share->state.key_map & ((ulonglong) 1 << i))) { - init_tree(& info->bulk_insert[i], 0, myisam_bulk_insert_tree_size, 0, - (qsort_cmp2)keys_compare, 0, - (tree_element_free) keys_free, (void *)params); + init_tree(& info->bulk_insert[i], 0, + myisam_bulk_insert_tree_size / share->base.keys, 0, + (qsort_cmp2)keys_compare, 0, + (tree_element_free) keys_free, (void *)params); } else info->bulk_insert[i].root=0; diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index 7b0050fb2eb..6d2660271ea 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -21,7 +21,7 @@ drop table t1; # --error 1064 select x'hello'; ---error 1064 +--error 1054 select 0xfg; # diff --git a/mysys/tree.c b/mysys/tree.c index f62710f4cdd..e02033ff413 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -97,7 +97,8 @@ void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit, DBUG_ENTER("init_tree"); DBUG_PRINT("enter",("tree: %lx size: %d",tree,size)); - default_alloc_size=DEFAULT_ALLOC_SIZE; + if (!default_alloc_size) + default_alloc_size= DEFAULT_ALLOC_SIZE; bzero((gptr) &tree->null_element,sizeof(tree->null_element)); tree->root= &tree->null_element; tree->compare=compare; diff --git a/sql/filesort.cc b/sql/filesort.cc index 3b59a0c09bb..3519467fbea 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -86,11 +86,10 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, my_b_clear(&tempfile); buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; maxbuffer=1; + bzero((char*) ¶m,sizeof(param)); param.ref_length= table->file->ref_length; param.sort_length=sortlength(sortorder,s_length)+ param.ref_length; param.max_rows= max_rows; - param.examined_rows=0; - param.unique_buff=0; if (select && select->quick) { @@ -686,9 +685,16 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, BUFFPEK *buffpek,**refpek; QUEUE queue; qsort2_cmp cmp; + volatile bool *killed= ¤t_thd->killed; + bool not_killable; DBUG_ENTER("merge_buffers"); statistic_increment(filesort_merge_passes, &LOCK_status); + if (param->not_killable) + { + killed= ¬_killable; + not_killable=0; + } error=0; offset=(sort_length=param->sort_length)-param->ref_length; @@ -738,6 +744,10 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, while (queue.elements > 1) { + if (*killed) + { + error=1; goto err; /* purecov: inspected */ + } for (;;) { buffpek=(BUFFPEK*) queue_top(&queue); diff --git a/sql/log_event.h b/sql/log_event.h index f38ddef05a2..d203894cf27 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -245,9 +245,9 @@ public: int get_data_size() { return q_len + db_len + 2 + - sizeof(uint32) // thread_id - + sizeof(uint32) // exec_time - + sizeof(uint16) // error_code + 4 // thread_id + + 4 // exec_time + + 2 // error_code ; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index afd4c6363ac..8fb28bb5aa7 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -222,5 +222,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index c481113e378..aa5ce318779 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -216,5 +216,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index c37554009ae..5aebadb910a 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index eadca864949..975227538c5 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index a27c7f4f9b7..33c061e1eeb 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -217,5 +217,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 18186b61204..bbdfbf8e1b5 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 073e33bd443..d12dc7caedc 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -216,5 +216,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 1e5d10eac17..b86e34e8cc4 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 6510c856b2d..80cc9da65f0 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -215,5 +215,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 070bc7ca8d1..08c91323c97 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index c52bd19d00c..ffea1e1ceee 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -215,5 +215,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 9f5db7b6f97..5359ed17c69 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index cac6a00fa92..cf4d0de9200 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -215,5 +215,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 059ccad2670..22d4e4b52bd 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -215,5 +215,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index efd36ac3049..31627a41d5c 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -217,5 +217,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index bf049ec6b43..8542b661698 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -213,5 +213,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 9272418e533..ed211d3694b 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -217,5 +217,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 0c369b3099c..7965ba0b789 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -216,5 +216,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 189180845d3..9504f817d1c 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -221,5 +221,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index e3ef7edd743..f20fa57dd31 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -214,5 +214,4 @@ "CREATE DATABASE not allowed while thread is holding global read lock", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"Error when executing command %s: %-.128s", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 10cc61579ff..9e866bc510a 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -209,9 +209,8 @@ "Lock wait timeout exceeded", "The total number of locks exceeds the lock table size", "Update locks cannot be acquired during a READ UNCOMMITTED transaction", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Error connecting to master: %-.128s", -"Error running query on master: %-.128s", -"Error in SHOW BINLOG EVENTS: %-.128s", -"Error in SHOW NEW MASTER: %-.128s", +"DROP DATABASE är inte tillåtet när man har ett globalt läs-lås", +"CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås", +"Fick fel vid anslutning till master: %-.128s", +"Fick fel vid utförande av command på mastern: %-.128s", +"Fick fel vid utförande av %s: %-.128s", diff --git a/sql/sql_class.h b/sql/sql_class.h index 14055a1444c..eae0213e6e1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -421,7 +421,7 @@ public: virtual int prepare(List<Item> &list) { return 0; } virtual bool send_fields(List<Item> &list,uint flag)=0; virtual bool send_data(List<Item> &items)=0; - virtual void initialize_tables (JOIN *join=0) {}; + virtual void initialize_tables (JOIN *join=0) {} virtual void send_error(uint errcode,const char *err)=0; virtual bool send_eof()=0; virtual void abort() {} diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 0f70bd71ddd..67fed1c77ba 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sinisa +/* Copyright (C) 2000 MySQL AB 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 @@ -316,14 +316,14 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, #endif (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); - (void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); /* Don't use key read with MULTI-TABLE-DELETE */ + (void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); dt->table->used_keys=0; for (dt=dt->next ; dt ; dt=dt->next,counter++) { TABLE *table=dt->table; - (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); - (void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); + (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); + (void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); #ifdef SINISAS_STRIP tempfiles[counter]=(IO_CACHE *) sql_alloc(sizeof(IO_CACHE)); if (open_cached_file(tempfiles[counter], mysql_tmpdir,TEMP_PREFIX, @@ -366,50 +366,38 @@ multi_delete::prepare(List<Item> &values) DBUG_RETURN(0); } -inline static void -link_in_list(SQL_LIST *list,byte *element,byte **next) -{ - list->elements++; - (*list->next)=element; - list->next=next; - *next=0; -} void multi_delete::initialize_tables(JOIN *join) { - SQL_LIST *new_list=(SQL_LIST *) sql_alloc(sizeof(SQL_LIST)); - new_list->elements=0; new_list->first=0; - new_list->next= (byte**) &(new_list->first); + TABLE_LIST *walk; + table_map tables_to_delete_from=0; + for (walk= delete_tables ; walk ; walk=walk->next) + tables_to_delete_from|= walk->table->map; + + walk= delete_tables; for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; tab < end; tab++) { - TABLE_LIST *walk; - for (walk=(TABLE_LIST*) delete_tables ; walk ; walk=walk->next) - if (!strcmp(tab->table->path,walk->table->path)) - break; - if (walk) // Table need not be the one to be deleted + if (tab->table->map & tables_to_delete_from) { - register TABLE_LIST *ptr = (TABLE_LIST *) sql_alloc(sizeof(TABLE_LIST)); - memcpy(ptr,walk,sizeof(TABLE_LIST)); ptr->next=0; - link_in_list(new_list,(byte*) ptr,(byte**) &ptr->next); + /* We are going to delete from this table */ + walk->table=tab->table; + walk=walk->next; } } - delete_tables=(TABLE_LIST *)new_list->first; - return; } + multi_delete::~multi_delete() { - /* Add back EXTRA_READCHECK; In 4.0.1 we shouldn't need this anymore */ for (table_being_deleted=delete_tables ; table_being_deleted ; table_being_deleted=table_being_deleted->next) - { - VOID(table_being_deleted->table->file->extra(HA_EXTRA_READCHECK)); - } + (void) table_being_deleted->table->file->extra(HA_EXTRA_READCHECK); + for (uint counter = 0; counter < num_of_tables-1; counter++) { if (tempfiles[counter]) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 2fd7f29c560..176122a3f59 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha 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 @@ -76,13 +76,8 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN]; memset(header, 0, 4); // when does not matter header[EVENT_TYPE_OFFSET] = ROTATE_EVENT; - char* p = strrchr(log_file_name, FN_LIBCHAR); - // find the last slash - if(p) - p++; - else - p = log_file_name; + char* p = log_file_name+dirname_length(log_file_name); uint ident_len = (uint) strlen(p); ulong event_len = ident_len + ROTATE_EVENT_OVERHEAD; int4store(header + SERVER_ID_OFFSET, server_id); @@ -93,59 +88,55 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, int8store(buf, 4); // tell slave to skip magic number packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); - if(my_net_write(net, (char*)packet->ptr(), packet->length())) - { - *errmsg = "failed on my_net_write()"; - return -1; - } + if (my_net_write(net, (char*)packet->ptr(), packet->length())) + { + *errmsg = "failed on my_net_write()"; + return -1; + } return 0; } +#define get_object(p, obj) \ +{\ + uint len = (uint)*p++; \ + if (p + len > p_end || len >= sizeof(obj)) \ + goto err; \ + strmake(obj,(char*) p,len); \ + p+= len; \ +}\ + + int register_slave(THD* thd, uchar* packet, uint packet_length) { uint len; - SLAVE_INFO* si, *old_si; + SLAVE_INFO *si, *old_si; int res = 1; uchar* p = packet, *p_end = packet + packet_length; - if(check_access(thd, FILE_ACL, any_db)) + if (check_access(thd, FILE_ACL, any_db)) return 1; - - if(!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME)))) + + if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME)))) goto err; si->server_id = uint4korr(p); p += 4; - len = (uint)*p++; - if(p + len > p_end || len > sizeof(si->host) - 1) - goto err; - memcpy(si->host, p, len); - si->host[len] = 0; - p += len; - len = *p++; - if(p + len > p_end || len > sizeof(si->user) - 1) - goto err; - memcpy(si->user, p, len); - si->user[len] = 0; - p += len; - len = *p++; - if(p + len > p_end || len > sizeof(si->password) - 1) - goto err; - memcpy(si->password, p, len); - si->password[len] = 0; - p += len; + get_object(p,si->host); + get_object(p,si->user); + get_object(p,si->password); si->port = uint2korr(p); pthread_mutex_lock(&LOCK_slave_list); - if((old_si = (SLAVE_INFO*)hash_search(&slave_list, + if ((old_si = (SLAVE_INFO*)hash_search(&slave_list, (byte*)&si->server_id, 4))) hash_delete(&slave_list, (byte*)old_si); - - res = hash_insert(&slave_list, (byte*)si); + + res = hash_insert(&slave_list, (byte*) si); pthread_mutex_unlock(&LOCK_slave_list); return res; + err: - if(si) + if (si) my_free((byte*)si, MYF(MY_WME)); return res; } @@ -156,10 +147,10 @@ static int send_file(THD *thd) NET* net = &thd->net; int fd = -1,bytes, error = 1; char fname[FN_REFLEN+1]; - char *buf; const char *errmsg = 0; int old_timeout; uint packet_len; + char buf[IO_SIZE]; // It's safe to alloc this DBUG_ENTER("send_file"); // the client might be slow loading the data, give him wait_timeout to do @@ -167,40 +158,32 @@ static int send_file(THD *thd) old_timeout = thd->net.timeout; thd->net.timeout = thd->inactive_timeout; - // spare the stack - if(!(buf = alloc_root(&thd->mem_root,IO_SIZE))) - { - errmsg = "Out of memory"; - goto err; - } - // we need net_flush here because the client will not know it needs to send // us the file name until it has processed the load event entry if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error) { - errmsg = "Failed reading file name"; + errmsg = "while reading file name"; goto err; } - *((char*)net->read_pos + packet_len) = 0; // terminate with \0 - //for fn_format - fn_format(fname, (char*)net->read_pos + 1, "", "", 4); + // terminate with \0 for fn_format + *((char*)net->read_pos + packet_len) = 0; + fn_format(fname, (char*) net->read_pos + 1, "", "", 4); // this is needed to make replicate-ignore-db if (!strcmp(fname,"/dev/null")) goto end; - if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) + if ((fd = my_open(fname, O_RDONLY, MYF(0))) < 0) { - errmsg = "Failed on my_open()"; + errmsg = "on open of file"; goto err; } - while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, - MYF(MY_WME))) > 0) + while ((bytes = (int) my_read(fd, (byte*) buf, IO_SIZE, MYF(0))) > 0) { if (my_net_write(net, buf, bytes)) { - errmsg = "Failed on my_net_write()"; + errmsg = "while writing data to client"; goto err; } } @@ -209,18 +192,18 @@ static int send_file(THD *thd) if (my_net_write(net, "", 0) || net_flush(net) || (my_net_read(net) == packet_error)) { - errmsg = "failed negotiating file transfer close"; + errmsg = "while negotiating file transfer close"; goto err; } error = 0; err: thd->net.timeout = old_timeout; - if(fd >= 0) - (void) my_close(fd, MYF(MY_WME)); + if (fd >= 0) + (void) my_close(fd, MYF(0)); if (errmsg) { - sql_print_error("failed in send_file() : %s", errmsg); + sql_print_error("Failed in send_file() %s", errmsg); DBUG_PRINT("error", (errmsg)); } DBUG_RETURN(error); @@ -228,34 +211,37 @@ static int send_file(THD *thd) File open_binlog(IO_CACHE *log, const char *log_file_name, - const char **errmsg) + const char **errmsg) { File file; char magic[4]; + 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, MYF(MY_WME))) { - *errmsg = "Could not open log file"; // This will not be sent + *errmsg = "Could not open log file"; // This will not be sent goto err; } - + if (my_b_read(log, (byte*) magic, sizeof(magic))) { - *errmsg = "I/O error reading binlog magic number"; + *errmsg = "I/O error reading the header from the binary log"; goto err; } - if (memcmp(magic, BINLOG_MAGIC, 4)) + if (memcmp(magic, BINLOG_MAGIC, sizeof(magic))) { - *errmsg = "Binlog has bad magic number, fire your magician"; + *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; err: - if (file > 0) + if (file >= 0) + { my_close(file,MYF(0)); - end_io_cache(log); + end_io_cache(log); + } return -1; } @@ -263,26 +249,26 @@ err: void adjust_linfo_offsets(my_off_t purge_offset) { THD *tmp; - + pthread_mutex_lock(&LOCK_thread_count); I_List_iterator<THD> it(threads); - - while((tmp=it++)) - { - LOG_INFO* linfo; - if((linfo = tmp->current_linfo)) - { - pthread_mutex_lock(&linfo->lock); - // no big deal if we just started reading the log - // nothing to adjust - if(linfo->index_file_offset < purge_offset) - linfo->fatal = (linfo->index_file_offset != 0); - else - linfo->index_file_offset -= purge_offset; - pthread_mutex_unlock(&linfo->lock); - } - } + while ((tmp=it++)) + { + LOG_INFO* linfo; + if ((linfo = tmp->current_linfo)) + { + pthread_mutex_lock(&linfo->lock); + // Why (monty): I don't understand this comment + // no big deal if we just started reading the log + // nothing to adjust + if (linfo->index_file_offset < purge_offset) + linfo->fatal = (linfo->index_file_offset != 0); + else + linfo->index_file_offset -= purge_offset; + pthread_mutex_unlock(&linfo->lock); + } + } pthread_mutex_unlock(&LOCK_thread_count); } @@ -292,21 +278,21 @@ bool log_in_use(const char* log_name) int log_name_len = strlen(log_name) + 1; THD *tmp; bool result = 0; - + pthread_mutex_lock(&LOCK_thread_count); I_List_iterator<THD> it(threads); - - while((tmp=it++)) + + while ((tmp=it++)) + { + LOG_INFO* linfo; + if ((linfo = tmp->current_linfo)) { - LOG_INFO* linfo; - if((linfo = tmp->current_linfo)) - { - pthread_mutex_lock(&linfo->lock); - result = !memcmp(log_name, linfo->log_file_name, log_name_len); - pthread_mutex_unlock(&linfo->lock); - if(result) break; - } - } + pthread_mutex_lock(&linfo->lock); + result = !memcmp(log_name, linfo->log_file_name, log_name_len); + pthread_mutex_unlock(&linfo->lock); + if (result) break; + } + } pthread_mutex_unlock(&LOCK_thread_count); return result; @@ -316,35 +302,35 @@ bool log_in_use(const char* log_name) int purge_master_logs(THD* thd, const char* to_log) { char search_file_name[FN_REFLEN]; + const char* errmsg = 0; + mysql_bin_log.make_log_name(search_file_name, to_log); int res = mysql_bin_log.purge_logs(thd, search_file_name); - const char* errmsg = 0; - switch(res) - { - case 0: break; - case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break; - case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break; - case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \ + + switch(res) { + case 0: break; + case LOG_INFO_EOF: errmsg = "Target log not found in binlog index"; break; + case LOG_INFO_IO: errmsg = "I/O error reading log index file"; break; + case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \ binlog purge"; break; - case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break; - case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log"; - break; - case LOG_INFO_MEM: errmsg = "Out of memory"; break; - case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break; - case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge"; - break; - default: - errmsg = "Unknown error during purge"; break; - } - - if(errmsg) - { - send_error(&thd->net, 0, errmsg); - return 1; - } + case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break; + case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log"; + break; + case LOG_INFO_MEM: errmsg = "Out of memory"; break; + case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break; + case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge"; + break; + default: errmsg = "Unknown error during purge"; break; + } + + if (errmsg) + { + send_error(&thd->net, 0, errmsg); + return 1; + } else send_ok(&thd->net); - + return 0; } @@ -362,7 +348,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) NET* net = &thd->net; #ifndef DBUG_OFF int left_events = max_binlog_dump_events; -#endif +#endif DBUG_ENTER("mysql_binlog_send"); #ifndef DBUG_OFF @@ -371,26 +357,26 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) errmsg = "Master failed COM_BINLOG_DUMP to test if slave can recover"; goto err; } -#endif +#endif bzero((char*) &log,sizeof(log)); - if(!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open()) { errmsg = "Binary log is not open"; goto err; } - if(!server_id_supplied) - { - errmsg = "Misconfigured master - server id was not set"; - goto err; - } - + if (!server_id_supplied) + { + errmsg = "Misconfigured master - server id was not set"; + goto err; + } + if (log_ident[0]) mysql_bin_log.make_log_name(search_file_name, log_ident); else search_file_name[0] = 0; - + linfo.index_file_offset = 0; thd->current_linfo = &linfo; @@ -409,17 +395,17 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) impossible position"; goto err; } - + my_b_seek(&log, pos); // Seek will done on next read packet->length(0); - packet->append("\0", 1); // we need to start a packet with something other than 255 // to distiquish it from error + packet->append("\0", 1); - // tell the client log name with a fake rotate_event // if we are at the start of the log - if(pos == 4) + if (pos == 4) { + // tell the client log name with a fake rotate_event if (fake_rotate_event(net, packet, log_file_name, &errmsg)) goto err; packet->length(0); @@ -429,17 +415,17 @@ impossible position"; while (!net->error && net->vio != 0 && !thd->killed) { pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); - + while (!(error = Log_event::read_log_event(&log, packet, log_lock))) { #ifndef DBUG_OFF - if(max_binlog_dump_events && !left_events--) + if (max_binlog_dump_events && !left_events--) { net_flush(net); errmsg = "Debugging binlog dump abort"; goto err; } -#endif +#endif if (my_net_write(net, (char*)packet->ptr(), packet->length()) ) { errmsg = "Failed on my_net_write()"; @@ -449,7 +435,7 @@ impossible position"; (*packet)[LOG_EVENT_OFFSET+1] )); if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) { - if(send_file(thd)) + if (send_file(thd)) { errmsg = "failed in send_file()"; goto err; @@ -458,15 +444,14 @@ impossible position"; packet->length(0); packet->append("\0",1); } - + if (error != LOG_READ_EOF) { - switch(error) - { - case LOG_READ_BOGUS: + switch(error) { + case LOG_READ_BOGUS: errmsg = "bogus data in log event"; break; - case LOG_READ_TOO_LARGE: + case LOG_READ_TOO_LARGE: errmsg = "log event entry exceeded max_allowed_packet -\ increase max_allowed_packet on master"; break; @@ -486,12 +471,12 @@ impossible position"; goto err; } - if(!(flags & BINLOG_DUMP_NON_BLOCK) && + if (!(flags & BINLOG_DUMP_NON_BLOCK) && mysql_bin_log.is_active(log_file_name)) + { // block until there is more data in the log // unless non-blocking mode requested - { - if(net_flush(net)) + if (net_flush(net)) { errmsg = "failed on net_flush()"; goto err; @@ -515,13 +500,13 @@ impossible position"; bool read_packet = 0, fatal_error = 0; #ifndef DBUG_OFF - if(max_binlog_dump_events && !left_events--) + if (max_binlog_dump_events && !left_events--) { net_flush(net); errmsg = "Debugging binlog dump abort"; goto err; } -#endif +#endif // no one will update the log while we are reading // now, but we'll be quick and just read one record @@ -550,18 +535,18 @@ impossible position"; 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"; - if(my_net_write(net, (char*)packet->ptr(), packet->length()) ) + if (my_net_write(net, (char*)packet->ptr(), packet->length()) ) { errmsg = "Failed on my_net_write()"; goto err; } - if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) + if ((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT) { - if(send_file(thd)) + if (send_file(thd)) { errmsg = "failed in send_file()"; goto err; @@ -573,7 +558,7 @@ impossible position"; // we hit EOF pretty quick } - if(fatal_error) + if (fatal_error) { errmsg = "error reading log entry"; goto err; @@ -586,8 +571,7 @@ impossible position"; bool loop_breaker = 0; // need this to break out of the for loop from switch thd->proc_info = "switching to next log"; - switch(mysql_bin_log.find_next_log(&linfo)) - { + switch (mysql_bin_log.find_next_log(&linfo)) { case LOG_INFO_EOF: loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK); break; @@ -598,12 +582,12 @@ impossible position"; goto err; } - if(loop_breaker) + if (loop_breaker) break; end_io_cache(&log); (void) my_close(file, MYF(MY_WME)); - + // fake Rotate_log event just in case it did not make it to the log // otherwise the slave make get confused about the offset if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 || @@ -617,13 +601,14 @@ impossible position"; end_io_cache(&log); (void)my_close(file, MYF(MY_WME)); - + send_eof(&thd->net); thd->proc_info = "waiting to finalize termination"; pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; + err: thd->proc_info = "waiting to finalize termination"; end_io_cache(&log); @@ -643,50 +628,52 @@ impossible position"; int start_slave(THD* thd , bool net_report) { - if(!thd) thd = current_thd; - NET* net = &thd->net; int slave_errno = 0; + if (!thd) thd = current_thd; + NET* net = &thd->net; + if (check_access(thd, PROCESS_ACL, any_db)) return 1; pthread_mutex_lock(&LOCK_slave); - if(!slave_running) + if (!slave_running) + { + if (init_master_info(&glob_mi)) + slave_errno = ER_MASTER_INFO; + else if (server_id_supplied && *glob_mi.host) { - if(init_master_info(&glob_mi)) - slave_errno = ER_MASTER_INFO; - else if(server_id_supplied && *glob_mi.host) - { - pthread_t hThread; - if(pthread_create(&hThread, &connection_attrib, handle_slave, 0)) - { - slave_errno = ER_SLAVE_THREAD; - } - while(!slave_running) // slave might already be running by now - pthread_cond_wait(&COND_slave_start, &LOCK_slave); - } - else - slave_errno = ER_BAD_SLAVE; + pthread_t hThread; + if (pthread_create(&hThread, &connection_attrib, handle_slave, 0)) + { + slave_errno = ER_SLAVE_THREAD; + } + while (!slave_running) // slave might already be running by now + pthread_cond_wait(&COND_slave_start, &LOCK_slave); } + else + slave_errno = ER_BAD_SLAVE; + } else slave_errno = ER_SLAVE_MUST_STOP; pthread_mutex_unlock(&LOCK_slave); - if(slave_errno) - { - if(net_report) send_error(net, slave_errno); - return 1; - } - else if(net_report) + if (slave_errno) + { + if (net_report) send_error(net, slave_errno); + return 1; + } + else if (net_report) send_ok(net); return 0; } + int stop_slave(THD* thd, bool net_report ) { - if(!thd) thd = current_thd; - NET* net = &thd->net; int slave_errno = 0; - + if (!thd) thd = current_thd; + NET* net = &thd->net; + if (check_access(thd, PROCESS_ACL, any_db)) return 1; @@ -697,11 +684,11 @@ int stop_slave(THD* thd, bool net_report ) thr_alarm_kill(slave_real_id); #ifdef SIGNAL_WITH_VIO_CLOSE slave_thd->close_active_vio(); -#endif +#endif // do not abort the slave in the middle of a query, so we do not set // thd->killed for the slave thread thd->proc_info = "waiting for slave to die"; - while(slave_running) + while (slave_running) pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); } else @@ -710,17 +697,19 @@ int stop_slave(THD* thd, bool net_report ) pthread_mutex_unlock(&LOCK_slave); thd->proc_info = 0; - if(slave_errno) - { - if(net_report) send_error(net, slave_errno); - return 1; - } - else if(net_report) + if (slave_errno) + { + if (net_report) + send_error(net, slave_errno); + return 1; + } + else if (net_report) send_ok(net); return 0; } + void reset_slave() { MY_STAT stat_area; @@ -728,115 +717,113 @@ void reset_slave() bool slave_was_running ; pthread_mutex_lock(&LOCK_slave); - if((slave_was_running = slave_running)) - { + if ((slave_was_running = slave_running)) + { pthread_mutex_unlock(&LOCK_slave); stop_slave(0,0); - } + } else pthread_mutex_unlock(&LOCK_slave); - + end_master_info(&glob_mi); fn_format(fname, master_info_file, mysql_data_home, "", 4+32); - if(my_stat(fname, &stat_area, MYF(0))) - if(my_delete(fname, MYF(MY_WME))) - return; - if(slave_was_running) + if (my_stat(fname, &stat_area, MYF(0)) && my_delete(fname, MYF(MY_WME))) + return; + if (slave_was_running) start_slave(0,0); } + void kill_zombie_dump_threads(uint32 slave_server_id) { pthread_mutex_lock(&LOCK_thread_count); I_List_iterator<THD> it(threads); THD *tmp; - while((tmp=it++)) + while ((tmp=it++)) + { + if (tmp->command == COM_BINLOG_DUMP && + tmp->server_id == slave_server_id) { - if(tmp->command == COM_BINLOG_DUMP && - tmp->server_id == slave_server_id) - { - // here we do not call kill_one_thread() - // it will be slow because it will iterate through the list - // again. Plus it double-locks LOCK_thread_count, which - // make safe_mutex complain and abort - // so we just to our own thread murder - - thr_alarm_kill(tmp->real_id); - tmp->killed = 1; - pthread_mutex_lock(&tmp->mysys_var->mutex); - tmp->mysys_var->abort = 1; - if(tmp->mysys_var->current_mutex) - { - 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); + // here we do not call kill_one_thread() + // it will be slow because it will iterate through the list + // again. Plus it double-locks LOCK_thread_count, which + // make safe_mutex complain and abort + // so we just to our own thread murder + + thr_alarm_kill(tmp->real_id); + tmp->killed = 1; + pthread_mutex_lock(&tmp->mysys_var->mutex); + tmp->mysys_var->abort = 1; + if (tmp->mysys_var->current_mutex) + { + 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); } + int change_master(THD* thd) { bool slave_was_running; // kill slave thread pthread_mutex_lock(&LOCK_slave); - if((slave_was_running = slave_running)) - { - abort_slave = 1; - thr_alarm_kill(slave_real_id); - thd->proc_info = "waiting for slave to die"; - while(slave_running) - pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done - } + if ((slave_was_running = slave_running)) + { + abort_slave = 1; + thr_alarm_kill(slave_real_id); + thd->proc_info = "waiting for slave to die"; + while (slave_running) + pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done + } pthread_mutex_unlock(&LOCK_slave); thd->proc_info = "changing master"; LEX_MASTER_INFO* lex_mi = &thd->lex.mi; - if(init_master_info(&glob_mi)) - { - send_error(&thd->net, 0, "Could not initialize master info"); - return 1; - } - + if (init_master_info(&glob_mi)) + { + send_error(&thd->net, 0, "Could not initialize master info"); + return 1; + } + pthread_mutex_lock(&glob_mi.lock); - 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 - glob_mi.log_file_name[0] = 0; - glob_mi.pos = 4; // skip magic number - glob_mi.pending = 0; - } + 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 + glob_mi.log_file_name[0] = 0; + glob_mi.pos = 4; // skip magic number + glob_mi.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, sizeof(glob_mi.log_file_name)); - if(lex_mi->pos) + if (lex_mi->pos) { glob_mi.pos = lex_mi->pos; glob_mi.pending = 0; } - - if(lex_mi->host) - { - strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host)); - } - if(lex_mi->user) + + if (lex_mi->host) + strmake(glob_mi.host, lex_mi->host, sizeof(glob_mi.host)); + if (lex_mi->user) strmake(glob_mi.user, lex_mi->user, sizeof(glob_mi.user)); - if(lex_mi->password) + if (lex_mi->password) strmake(glob_mi.password, lex_mi->password, sizeof(glob_mi.password)); - if(lex_mi->port) + if (lex_mi->port) glob_mi.port = lex_mi->port; - if(lex_mi->connect_retry) + if (lex_mi->connect_retry) glob_mi.connect_retry = lex_mi->connect_retry; flush_master_info(&glob_mi); pthread_mutex_unlock(&glob_mi.lock); thd->proc_info = "starting slave"; - if(slave_was_running) + if (slave_was_running) start_slave(0,0); thd->proc_info = 0; @@ -844,9 +831,10 @@ int change_master(THD* thd) return 0; } + 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)); return; @@ -865,9 +853,9 @@ void reset_master() mysql_bin_log.close(1); // exiting close my_delete(mysql_bin_log.get_index_fname(), MYF(MY_WME)); mysql_bin_log.open(opt_bin_logname,LOG_BIN); - } + int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, const char* log_file_name2, ulonglong log_pos2) { @@ -881,6 +869,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, return -1; } + static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi) { return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name, @@ -891,7 +880,7 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) { uint32 log_seq = mi->last_log_seq; uint32 target_server_id = mi->server_id; - + for (;;) { Log_event* ev; @@ -899,7 +888,7 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) { if (log->error > 0) strmov(errmsg, "Binary log truncated in the middle of event"); - else if(log->error < 0) + else if (log->error < 0) strmov(errmsg, "I/O error reading binary log"); else strmov(errmsg, "Could not find target event in the binary log"); @@ -917,16 +906,6 @@ static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) } } -static void copy_base_name(char* dest, char* src) -{ - char* p; - p = strrchr(src, FN_LIBCHAR); - if (p) - p++; - else - p = src; - strmov(dest, p); -} int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) { @@ -941,7 +920,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) int error = 1; int cmp_res; LINT_INIT(cmp_res); - + if (!mysql_bin_log.is_open()) { strmov(errmsg,"Binary log is not open"); @@ -953,8 +932,18 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) strmov(errmsg, "Misconfigured master - server id was not set"); return 1; } - + linfo.index_file_offset = 0; + + /* + WARNING: POSSIBLE BUG: + Sasha, you are setting an uninitialized linfo into + thd->current_linfo. + What will happen if some other thread calls log_in_use() or + adjust_linfo_offsets() after the next instruction as linfo may + contain anything ? + */ + thd->current_linfo = &linfo; search_file_name[0] = 0; @@ -963,48 +952,40 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) strmov(errmsg,"Could not find first log"); return 1; } - + bzero((char*) &log,sizeof(log)); log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_lock(log_lock); - + for (;;) { - if ((file=open_binlog(&log, linfo.log_file_name, &errmsg_p)) < 0) { - pthread_mutex_unlock(log_lock); strmov(errmsg, errmsg_p); goto err; } - + if (!(sev = find_slave_event(&log, linfo.log_file_name, errmsg))) - { - pthread_mutex_unlock(log_lock); goto err; - } - + cmp_res = cmp_master_pos(sev, mi); delete sev; - - if(!cmp_res) + + if (!cmp_res) { - pthread_mutex_unlock(log_lock); - copy_base_name(mi->log_file_name, linfo.log_file_name); + /* Copy basename */ + fn_format(mi->log_file_name, linfo.log_file_name, "","",1); mi->pos = my_b_tell(&log); goto mi_inited; } - - if (!last_pos && cmp_res > 0) - { - pthread_mutex_unlock(log_lock); - strmov(errmsg, "Slave event in first log points past the \ -target position"); - goto err; - } - - if (last_pos && cmp_res > 0) + else if (cmp_res > 0) { + if (!last_pos) + { + strmov(errmsg, + "Slave event in first log points past the target position"); + goto err; + } end_io_cache(&log); (void) my_close(file, MYF(MY_WME)); if (init_io_cache(&log, (file = last_file), IO_SIZE, READ_CACHE, 0, 0, @@ -1013,15 +994,13 @@ target position"); errmsg[0] = 0; goto err; } - - goto found_log; + break; } - + strmov(last_log_name, linfo.log_file_name); last_pos = my_b_tell(&log); - switch (mysql_bin_log.find_next_log(&linfo)) - { + switch (mysql_bin_log.find_next_log(&linfo)) { case LOG_INFO_EOF: if (last_file >= 0) (void)my_close(last_file, MYF(MY_WME)); @@ -1030,29 +1009,26 @@ target position"); case 0: break; default: - pthread_mutex_unlock(log_lock); strmov(errmsg, "Error reading log index"); goto err; } - + end_io_cache(&log); if (last_file >= 0) (void) my_close(last_file, MYF(MY_WME)); last_file = file; } - + found_log: my_b_seek(&log, last_pos); if (find_target_pos(mi,&log,errmsg)) - { - pthread_mutex_unlock(log_lock); goto err; - } - pthread_mutex_unlock(log_lock); - copy_base_name(mi->log_file_name, last_log_name); -mi_inited: + fn_format(mi->log_file_name, last_log_name, "","",1); /* Copy basename */ + +mi_inited: error = 0; err: + pthread_mutex_unlock(log_lock); end_io_cache(&log); pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; @@ -1078,9 +1054,8 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, (char*)log_file_name); return 0; } - delete ev; - + if (!(ev = Log_event::read_log_event(log, 0))) { my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE, @@ -1101,20 +1076,23 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, return (Slave_log_event*)ev; } + int show_new_master(THD* thd) { DBUG_ENTER("show_new_master"); List<Item> field_list; char errmsg[SLAVE_ERRMSG_SIZE]; LEX_MASTER_INFO* lex_mi = &thd->lex.mi; - + + errmsg[0]=0; // Safety if (translate_master(thd, lex_mi, errmsg)) { if (errmsg[0]) - net_printf(&thd->net, ER_SHOW_NEW_MASTER, errmsg); + net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, + "SHOW NEW MASTER", errmsg); else send_error(&thd->net, 0); - + DBUG_RETURN(1); } else @@ -1142,11 +1120,11 @@ int show_binlog_events(THD* thd) const char* errmsg = 0; IO_CACHE log; File file = -1; - - Log_event::init_show_field_list(&field_list); + + Log_event::init_show_field_list(&field_list); if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); - + if (mysql_bin_log.is_open()) { LOG_INFO linfo; @@ -1156,7 +1134,7 @@ int show_binlog_events(THD* thd) const char* log_file_name = lex_mi->log_file_name; Log_event* ev; ulong pos = (ulong) lex_mi->pos; - + limit_start = thd->lex.select->offset_limit; limit_end = thd->lex.select->select_limit + limit_start; @@ -1167,7 +1145,7 @@ int show_binlog_events(THD* thd) linfo.index_file_offset = 0; thd->current_linfo = &linfo; - + if (mysql_bin_log.find_first_log(&linfo, search_file_name)) { errmsg = "Could not find target log"; @@ -1186,19 +1164,18 @@ int show_binlog_events(THD* thd) pthread_mutex_lock(mysql_bin_log.get_log_lock()); my_b_seek(&log, pos); - for (event_count = 0; - (ev = Log_event::read_log_event(&log, 0));) + for (event_count = 0; (ev = Log_event::read_log_event(&log, 0)); ) { if (event_count >= limit_start && - ev->net_send(thd, linfo.log_file_name, pos)) - { - errmsg = "Net error"; - delete ev; - pthread_mutex_unlock(mysql_bin_log.get_log_lock()); - goto err; - } - - pos = my_b_tell(&log); + ev->net_send(thd, linfo.log_file_name, pos)) + { + errmsg = "Net error"; + delete ev; + pthread_mutex_unlock(mysql_bin_log.get_log_lock()); + goto err; + } + + pos = my_b_tell(&log); delete ev; if (++event_count >= limit_end) @@ -1210,7 +1187,7 @@ int show_binlog_events(THD* thd) errmsg = "Wrong offset or I/O error"; goto err; } - + pthread_mutex_unlock(mysql_bin_log.get_log_lock()); } @@ -1220,10 +1197,11 @@ err: end_io_cache(&log); (void) my_close(file, MYF(MY_WME)); } - + if (errmsg) { - net_printf(&thd->net, ER_SHOW_BINLOG_EVENTS, errmsg); + net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, + "SHOW BINLOG EVENTS", errmsg); DBUG_RETURN(1); } @@ -1234,38 +1212,38 @@ err: int show_slave_hosts(THD* thd) { - DBUG_ENTER("show_slave_hosts"); List<Item> field_list; + NET* net = &thd->net; + String* packet = &thd->packet; + DBUG_ENTER("show_slave_hosts"); + field_list.push_back(new Item_empty_string("Server_id", 20)); field_list.push_back(new Item_empty_string("Host", 20)); - if(opt_show_slave_auth_info) + if (opt_show_slave_auth_info) { field_list.push_back(new Item_empty_string("User",20)); field_list.push_back(new Item_empty_string("Password",20)); } field_list.push_back(new Item_empty_string("Port",20)); - if(send_fields(thd, field_list, 1)) + if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); - String* packet = &thd->packet; - uint i; - NET* net = &thd->net; pthread_mutex_lock(&LOCK_slave_list); - - for(i = 0; i < slave_list.records; ++i) + + for (uint i = 0; i < slave_list.records; ++i) { - SLAVE_INFO* si = (SLAVE_INFO*)hash_element(&slave_list, i); + SLAVE_INFO* si = (SLAVE_INFO*) hash_element(&slave_list, i); packet->length(0); net_store_data(packet, si->server_id); net_store_data(packet, si->host); - if(opt_show_slave_auth_info) + if (opt_show_slave_auth_info) { net_store_data(packet, si->user); net_store_data(packet, si->password); } net_store_data(packet, (uint)si->port); - if(my_net_write(net, (char*)packet->ptr(), packet->length())) + if (my_net_write(net, (char*)packet->ptr(), packet->length())) { pthread_mutex_unlock(&LOCK_slave_list); DBUG_RETURN(-1); @@ -1276,6 +1254,7 @@ int show_slave_hosts(THD* thd) DBUG_RETURN(0); } + int show_binlog_info(THD* thd) { DBUG_ENTER("show_binlog_info"); @@ -1285,36 +1264,37 @@ int show_binlog_info(THD* thd) field_list.push_back(new Item_empty_string("Binlog_do_db",20)); field_list.push_back(new Item_empty_string("Binlog_ignore_db",20)); - if(send_fields(thd, field_list, 1)) + if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); String* packet = &thd->packet; packet->length(0); - if(mysql_bin_log.is_open()) - { - LOG_INFO li; - mysql_bin_log.get_current_log(&li); - int dir_len = dirname_length(li.log_file_name); - net_store_data(packet, li.log_file_name + dir_len); - net_store_data(packet, (longlong)li.pos); - net_store_data(packet, &binlog_do_db); - net_store_data(packet, &binlog_ignore_db); - } + if (mysql_bin_log.is_open()) + { + LOG_INFO li; + mysql_bin_log.get_current_log(&li); + int dir_len = dirname_length(li.log_file_name); + net_store_data(packet, li.log_file_name + dir_len); + net_store_data(packet, (longlong)li.pos); + net_store_data(packet, &binlog_do_db); + net_store_data(packet, &binlog_ignore_db); + } else - { - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - net_store_null(packet); - } + { + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + net_store_null(packet); + } - if(my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) + if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) DBUG_RETURN(-1); send_eof(&thd->net); DBUG_RETURN(0); } + int show_binlogs(THD* thd) { const char* errmsg = 0; @@ -1325,20 +1305,20 @@ int show_binlogs(THD* thd) String* packet = &thd->packet; IO_CACHE io_cache; uint length; - - if(!mysql_bin_log.is_open()) + + if (!mysql_bin_log.is_open()) { errmsg = "binlog is not open"; goto err; } field_list.push_back(new Item_empty_string("Log_name", 128)); - if(send_fields(thd, field_list, 1)) + if (send_fields(thd, field_list, 1)) { sql_print_error("Failed in send_fields"); return 1; } - + mysql_bin_log.lock_index(); index_file = mysql_bin_log.get_index_file(); if (index_file < 0) @@ -1358,7 +1338,7 @@ int show_binlogs(THD* thd) int dir_len = dirname_length(fname); packet->length(0); net_store_data(packet, fname + dir_len, length-dir_len); - if(my_net_write(net, (char*) packet->ptr(), packet->length())) + if (my_net_write(net, (char*) packet->ptr(), packet->length())) { sql_print_error("Failed in my_net_write"); end_io_cache(&io_cache); @@ -1366,10 +1346,10 @@ int show_binlogs(THD* thd) return 1; } } - + mysql_bin_log.unlock_index(); end_io_cache(&io_cache); - send_eof(net); + send_eof(net); return 0; err2: @@ -1380,9 +1360,10 @@ err: return 1; } + int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) { - if(!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, + if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) { sql_print_error("Connection to master failed: %s", @@ -1392,68 +1373,73 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) return 0; } + static inline void cleanup_mysql_results(MYSQL_RES* db_res, MYSQL_RES** cur, MYSQL_RES** start) { for( ; cur >= start; --cur) - if(*cur) + { + if (*cur) mc_mysql_free_result(*cur); + } mc_mysql_free_result(db_res); } + static inline int fetch_db_tables(THD* thd, MYSQL* mysql, const char* db, MYSQL_RES* table_res) { MYSQL_ROW row; - + for( row = mc_mysql_fetch_row(table_res); row; row = mc_mysql_fetch_row(table_res)) { TABLE_LIST table; const char* table_name = row[0]; int error; - if(table_rules_on) + if (table_rules_on) { table.next = 0; table.db = (char*)db; table.real_name = (char*)table_name; table.updating = 1; - if(!tables_ok(thd, &table)) + if (!tables_ok(thd, &table)) continue; } - - if((error = fetch_nx_table(thd, db, table_name, &glob_mi, mysql))) + + if ((error = fetch_nx_table(thd, db, table_name, &glob_mi, mysql))) return error; } return 0; } + int load_master_data(THD* thd) { MYSQL mysql; MYSQL_RES* master_status_res = 0; bool slave_was_running = 0; int error = 0; - + mc_mysql_init(&mysql); - pthread_mutex_lock(&LOCK_slave); // we do not want anyone messing with the slave at all for the entire // duration of the data load; + pthread_mutex_lock(&LOCK_slave); // first, kill the slave - if((slave_was_running = slave_running)) + if ((slave_was_running = slave_running)) { abort_slave = 1; thr_alarm_kill(slave_real_id); thd->proc_info = "waiting for slave to die"; - while(slave_running) + while (slave_running) pthread_cond_wait(&COND_slave_stopped, &LOCK_slave); // wait until done } - - if(connect_to_master(thd, &mysql, &glob_mi)) + + if (connect_to_master(thd, &mysql, &glob_mi)) { net_printf(&thd->net, error = ER_CONNECT_TO_MASTER, mc_mysql_error(&mysql)); @@ -1465,21 +1451,21 @@ int load_master_data(THD* thd) MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res; uint num_dbs; MYSQL_ROW row; - - if(mc_mysql_query(&mysql, "show databases", 0) || - !(db_res = mc_mysql_store_result(&mysql))) + + if (mc_mysql_query(&mysql, "show databases", 0) || + !(db_res = mc_mysql_store_result(&mysql))) { net_printf(&thd->net, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } - if(!(num_dbs = mc_mysql_num_rows(db_res))) + if (!(num_dbs = mc_mysql_num_rows(db_res))) goto err; // in theory, the master could have no databases at all // and run with skip-grant - - if(!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) + + if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) { net_printf(&thd->net, error = ER_OUTOFMEMORY); goto err; @@ -1489,46 +1475,48 @@ int load_master_data(THD* thd) // capabilities - to be replaced once online backup is working // we wait to issue FLUSH TABLES WITH READ LOCK for as long as we // can to minimize the lock time - if(mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) - || mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) || - !(master_status_res = mc_mysql_store_result(&mysql))) + if (mc_mysql_query(&mysql, "FLUSH TABLES WITH READ LOCK", 0) || + mc_mysql_query(&mysql, "SHOW MASTER STATUS",0) || + !(master_status_res = mc_mysql_store_result(&mysql))) { net_printf(&thd->net, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } - + // go through every table in every database, and if the replication // rules allow replicating it, get it table_res_end = table_res + num_dbs; for(cur_table_res = table_res; cur_table_res < table_res_end; - ++cur_table_res) + cur_table_res++) { - MYSQL_ROW row = mc_mysql_fetch_row(db_res); // since we know how many rows we have, this can never be NULL - + MYSQL_ROW row = mc_mysql_fetch_row(db_res); char* db = row[0]; - int drop_error = 0; - - // do not replicate databases excluded by rules - // also skip mysql database - in most cases the user will - // mess up and not exclude mysql database with the rules when - // he actually means to - in this case, he is up for a surprise if - // his priv tables get dropped and downloaded from master - // TO DO - add special option, not enabled - // by default, to allow inclusion of mysql database into load - // data from master - if(!db_ok(db, replicate_do_db, replicate_ignore_db) || + int drop_error; + + /* + Do not replicate databases excluded by rules + also skip mysql database - in most cases the user will + mess up and not exclude mysql database with the rules when + he actually means to - in this case, he is up for a surprise if + his priv tables get dropped and downloaded from master + TO DO - add special option, not enabled + by default, to allow inclusion of mysql database into load + data from master + */ + + if (!db_ok(db, replicate_do_db, replicate_ignore_db) || !strcmp(db,"mysql")) { *cur_table_res = 0; continue; } - - if((drop_error = mysql_rm_db(0, db, 1)) || - mysql_create_db(0, db, 0)) + + if ((drop_error = mysql_rm_db(0, db, 1)) || + mysql_create_db(0, db, 0)) { error = (drop_error) ? ER_DB_DROP_DELETE : ER_CANT_CREATE_DB; net_printf(&thd->net, error, db, my_error); @@ -1536,8 +1524,8 @@ int load_master_data(THD* thd) goto err; } - if(mc_mysql_select_db(&mysql, db) || - mc_mysql_query(&mysql, "show tables", 0) || + if (mc_mysql_select_db(&mysql, db) || + mc_mysql_query(&mysql, "show tables", 0) || !(*cur_table_res = mc_mysql_store_result(&mysql))) { net_printf(&thd->net, error = ER_QUERY_ON_MASTER, @@ -1546,7 +1534,7 @@ int load_master_data(THD* thd) goto err; } - if((error = fetch_db_tables(thd, &mysql, db, *cur_table_res))) + if ((error = fetch_db_tables(thd, &mysql, db, *cur_table_res))) { // we do not report the error - fetch_db_tables handles it cleanup_mysql_results(db_res, cur_table_res, table_res); @@ -1557,44 +1545,44 @@ int load_master_data(THD* thd) cleanup_mysql_results(db_res, cur_table_res - 1, table_res); // adjust position in the master - if(master_status_res) + if (master_status_res) { MYSQL_ROW row = mc_mysql_fetch_row(master_status_res); - // we need this check because the master may not be running with - // log-bin, but it will still allow us to do all the steps - // of LOAD DATA FROM MASTER - no reason to forbid it, really, - // although it does not make much sense for the user to do it - if(row[0] && row[1]) + /* + We need this check because the master may not be running with + log-bin, but it will still allow us to do all the steps + of LOAD DATA FROM MASTER - no reason to forbid it, really, + although it does not make much sense for the user to do it + */ + if (row[0] && row[1]) { strmake(glob_mi.log_file_name, row[0], sizeof(glob_mi.log_file_name)); glob_mi.pos = atoi(row[1]); // atoi() is ok, since offset is <= 1GB - if(glob_mi.pos < 4) - glob_mi.pos = 4; // don't hit the magic number + if (glob_mi.pos < 4) + glob_mi.pos = 4; // don't hit the magic number glob_mi.pending = 0; flush_master_info(&glob_mi); } mc_mysql_free_result(master_status_res); } - - if(mc_mysql_query(&mysql, "UNLOCK TABLES", 0)) + + if (mc_mysql_query(&mysql, "UNLOCK TABLES", 0)) { net_printf(&thd->net, error = ER_QUERY_ON_MASTER, mc_mysql_error(&mysql)); goto err; } } -err: + +err: pthread_mutex_unlock(&LOCK_slave); - if(slave_was_running) + if (slave_was_running) start_slave(0, 0); mc_mysql_close(&mysql); // safe to call since we always do mc_mysql_init() - if(!error) + if (!error) send_ok(&thd->net); - + return error; } - - - diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 199d6a764e0..2fe8cc200af 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -110,7 +110,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild) if (send_fields(thd,field_list,1)) DBUG_RETURN(1); - if (!(open_list=list_open_tables(thd,wild))) + if (!(open_list=list_open_tables(thd,wild)) && thd->fatal_error) DBUG_RETURN(-1); for ( ; open_list ; open_list=open_list->next) diff --git a/sql/sql_sort.h b/sql/sql_sort.h index 498a5262b53..62c5f1cb164 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -37,6 +37,7 @@ typedef struct st_sort_param { SORT_FIELD *local_sortorder; SORT_FIELD *end; uchar *unique_buff; + bool not_killable; #ifdef USE_STRCOLL char* tmp_buffer; #endif diff --git a/sql/uniques.cc b/sql/uniques.cc index 5ef7ead276b..ee1da0f661b 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -128,10 +128,12 @@ bool Unique::get(TABLE *table) return 1; reinit_io_cache(outfile,WRITE_CACHE,0L,0,0); + bzero((char*) &sort_param,sizeof(sort_param)); sort_param.max_rows= elements; sort_param.sort_form=table; sort_param.sort_length=sort_param.ref_length=tree.size_of_element; sort_param.keys= max_in_memory_size / sort_param.sort_length; + sort_param.not_killable=1; if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) * sort_param.sort_length, |