diff options
60 files changed, 703 insertions, 139 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 0898b3d576f..9d3197c0bd4 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -253,4 +253,5 @@ #define ER_CANT_USE_OPTION_HERE 1234 #define ER_NOT_SUPPORTED_YET 1235 #define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 -#define ER_ERROR_MESSAGES 237 +#define ER_SLAVE_IGNORED_TABLE 1237 /* only the slave SQL thread can be sent this */ +#define ER_ERROR_MESSAGES 238 diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index af73c2f62c3..51231de4d77 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1937,7 +1937,8 @@ row_drop_table_for_mysql( " found := 0;\n" " ELSE" " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" - " DELETE FROM SYS_INDEXES WHERE ID = index_id;\n" + " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" + " AND TABLE_ID = table_id;\n" " END IF;\n" "END LOOP;\n" "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 083cbfd2609..a2314cde2dd 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -3009,10 +3009,29 @@ background_loop: srv_main_thread_op_info = (char*)"purging"; - if (srv_fast_shutdown && srv_shutdown_state > 0) { - n_pages_purged = 0; - } else { - n_pages_purged = trx_purge(); + /* Run a full purge */ + + n_pages_purged = 1; + + last_flush_time = time(NULL); + + while (n_pages_purged) { + if (srv_fast_shutdown && srv_shutdown_state > 0) { + + break; + } + + srv_main_thread_op_info = (char*)"purging"; + n_pages_purged = trx_purge(); + + current_time = time(NULL); + + if (difftime(current_time, last_flush_time) > 1) { + srv_main_thread_op_info = (char*) "flushing log"; + + log_buffer_flush_to_disk(); + last_flush_time = current_time; + } } srv_main_thread_op_info = (char*)"reserving kernel mutex"; diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index d58240d3c11..fa9c287b0ad 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -593,7 +593,7 @@ trx_purge_rseg_get_next_history_log( mutex_enter(&(rseg->mutex)); - ut_ad(rseg->last_page_no != FIL_NULL); + ut_a(rseg->last_page_no != FIL_NULL); purge_sys->purge_trx_no = ut_dulint_add(rseg->last_trx_no, 1); purge_sys->purge_undo_no = ut_dulint_zero; @@ -606,16 +606,9 @@ trx_purge_rseg_get_next_history_log( log_hdr = undo_page + rseg->last_offset; seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - if ((mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG) == 0) - && (mach_read_from_2(seg_hdr + TRX_UNDO_STATE) - == TRX_UNDO_TO_PURGE)) { - - /* This is the last log header on this page and the log - segment cannot be reused: we may increment the number of - pages handled */ + /* Increase the purge page count by one for every handled log */ - purge_sys->n_pages_handled++; - } + purge_sys->n_pages_handled++; prev_log_addr = trx_purge_get_log_from_hist( flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 0dead50264b..e8d6c093680 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -86,6 +86,10 @@ trx_create( trx->start_time = time(NULL); trx->isolation_level = TRX_ISO_REPEATABLE_READ; + + trx->id = ut_dulint_zero; + trx->no = ut_dulint_max; + trx->check_foreigns = TRUE; trx->check_unique_secondary = TRUE; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 7682d60d991..eddb326f6c4 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -511,17 +511,17 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, - LOG_NORMAL); + LOG_NORMAL, 0, 0, 0); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW); + NullS, LOG_NEW, 0, 0, 0); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - NullS, LOG_NORMAL); + NullS, LOG_NORMAL, 0, 0, 0); if (ha_init()) { sql_print_error("Can't init databases"); @@ -586,7 +586,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); } open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - opt_binlog_index_name, LOG_BIN); + opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size); using_update_log=1; } diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 75057dd4e6a..ef82a6ef61f 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -273,6 +273,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) } break; case HA_EXTRA_FORCE_REOPEN: + pthread_mutex_lock(&THR_LOCK_myisam); + share->last_version= 0L; /* Impossible version */ + pthread_mutex_unlock(&THR_LOCK_myisam); + break; case HA_EXTRA_PREPARE_FOR_DELETE: pthread_mutex_lock(&THR_LOCK_myisam); share->last_version= 0L; /* Impossible version */ diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index e2d9cc30ad9..7ade3313abe 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -281,3 +281,72 @@ ALTER TABLE t1 DISABLE KEYS; INSERT DELAYED INTO t1 VALUES(1),(2),(3); ALTER TABLE t1 ENABLE KEYS; drop table t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User) +) TYPE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty'); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 3 NULL NULL BTREE +ALTER TABLE t1 ENABLE KEYS; +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) TYPE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +ALTER TABLE t1 ENABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A 1 NULL NULL BTREE +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +LOCK TABLES t1 WRITE; +ALTER TABLE t1 RENAME t2; +UNLOCK TABLES; +select * from t2; +Host User +localhost +localhost root +DROP TABLE t2; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) TYPE=MyISAM; +LOCK TABLES t1 WRITE; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +DROP TABLE t1; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 6f15b2eb973..646c1a7bee2 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -5,9 +5,6 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), ('Only MyISAM tables','support collections'), ('Function MATCH ... AGAINST()','is used to do a search'), ('Full-text search in MySQL', 'implements vector space model'); -explain select * from t1 where MATCH(a,b) AGAINST ("collections"); -table type possible_keys key key_len ref rows Extra -t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST ("collections"); a b Only MyISAM tables support collections @@ -19,11 +16,36 @@ select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); a b Full-text indexes are called collections Only MyISAM tables support collections -select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); -a b -Only MyISAM tables support collections -Full-text indexes are called collections -Full-text indexes are called collections +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 5 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where 0<MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where 1<MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where 0<=MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 5 Using where +explain select * from t1 where 1<=MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0 and a like '%ll%'; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE); a b MySQL has now support for full-text search @@ -98,6 +120,11 @@ select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE); a b MySQL has now support for full-text search Function MATCH ... AGAINST() is used to do a search +select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); +a b +Only MyISAM tables support collections +Full-text indexes are called collections +Full-text indexes are called collections delete from t1 where a like "MySQL%"; update t1 set a='some test foobar' where MATCH a,b AGAINST ('model'); delete from t1 where MATCH(a,b) AGAINST ("indexes"); diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result new file mode 100644 index 00000000000..826e97a8004 --- /dev/null +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -0,0 +1,15 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +create table t1 (a int primary key); +insert into t1 values (1),(1); +Duplicate entry '1' for key 1 +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254 +show tables like 't1'; +Tables_in_test (t1) +drop table t1; diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index da2930f30c3..3273ce43a17 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -14,4 +14,4 @@ slave start; flush logs; show slave status; 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 Relay_log_space -127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.001 119 slave-bin.001 Yes Yes 0 0 79 119 +127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.002 119 slave-bin.001 Yes Yes 0 0 79 119 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 616ad319880..640e6f02103 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1) slave-bin.002 122 Query 1 228 use test; drop table t1 show slave status; 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 Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1563 +127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.003 211 master-bin.002 Yes Yes 0 0 276 211 show binlog events in 'slave-bin.005' from 4; Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result new file mode 100644 index 00000000000..5c5a9d622e5 --- /dev/null +++ b/mysql-test/r/rpl_max_relay_size.result @@ -0,0 +1,61 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +stop slave; +create table t1 (a int); +drop table t1; +reset slave; +set global max_binlog_size=8192; +set global max_relay_log_size=8192-1; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +4096 +start slave; +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 +stop slave; +reset slave; +set global max_relay_log_size=(5*4096); +select @@global.max_relay_log_size; +@@global.max_relay_log_size +20480 +start slave; +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +stop slave; +reset slave; +set global max_relay_log_size=0; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +0 +start slave; +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 +stop slave; +reset slave; +flush logs; +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +reset slave; +start slave; +flush logs; +create table t1 (a int); +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 +flush logs; +drop table t1; +show slave status; +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 Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 +flush logs; +show master status; +File Position Binlog_do_db Binlog_ignore_db +master-bin.002 4 diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index f49006e8e05..07490744d81 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -65,17 +65,15 @@ show master logs; Log_name master-bin.003 master-bin.004 -master-bin.005 -master-bin.006 show master status; File Position Binlog_do_db Binlog_ignore_db -master-bin.006 838 +master-bin.004 2886 select * from t4; a testing temporary tables part 2 show slave status; 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 Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.006 838 slave-relay-bin.001 8034 master-bin.006 Yes Yes 0 0 838 8034 +127.0.0.1 root MASTER_PORT 60 master-bin.004 2886 slave-relay-bin.001 7870 master-bin.004 Yes Yes 0 0 2886 7870 lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index a3ab62afc69..d438f2d5825 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -142,3 +142,65 @@ ALTER TABLE t1 DISABLE KEYS; INSERT DELAYED INTO t1 VALUES(1),(2),(3); ALTER TABLE t1 ENABLE KEYS; drop table t1; + +# +# Test ALTER TABLE ENABLE/DISABLE keys when things are locked +# + +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User) +) TYPE=MyISAM; + +ALTER TABLE t1 DISABLE KEYS; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty'); +SHOW INDEX FROM t1; +ALTER TABLE t1 ENABLE KEYS; +UNLOCK TABLES; +CHECK TABLES t1; +DROP TABLE t1; + +# +# Test with two keys +# + +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User), + KEY (Host) +) TYPE=MyISAM; + +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''); +SHOW INDEX FROM t1; +ALTER TABLE t1 ENABLE KEYS; +SHOW INDEX FROM t1; +UNLOCK TABLES; +CHECK TABLES t1; + +# Test RENAME with LOCK TABLES +LOCK TABLES t1 WRITE; +ALTER TABLE t1 RENAME t2; +UNLOCK TABLES; +select * from t2; +DROP TABLE t2; + +# +# Test disable keys with locking +# +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User), + KEY (Host) +) TYPE=MyISAM; + +LOCK TABLES t1 WRITE; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 1cc692bd886..79770a17baa 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -273,11 +273,14 @@ CREATE TABLE t2 (a int primary key, b int, c int); INSERT t2 VALUES (3,4,5); SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c; DROP TABLE IF EXISTS t1,t2; + +# +# Test of LEFT() with distinct +# + CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ; INSERT INTO t1 VALUES (1, 'aaaaa'); INSERT INTO t1 VALUES (3, 'aaaaa'); INSERT INTO t1 VALUES (2, 'eeeeeee'); select distinct left(name,1) as name from t1; drop table t1; - - diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 1b85f5903df..942552f5e98 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -12,14 +12,24 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), ('Full-text search in MySQL', 'implements vector space model'); # nl search - -explain select * from t1 where MATCH(a,b) AGAINST ("collections"); + select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("indexes"); select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); -# UNION of fulltext's -select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); + +# add_ft_keys() tests + +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1; +explain select * from t1 where 0<MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where 1<MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where 0<=MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where 1<=MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0 and a like '%ll%'; # boolean search @@ -48,6 +58,10 @@ select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE); select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE); +# UNION of fulltext's + +select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); + #update/delete with fulltext index delete from t1 where a like "MySQL%"; diff --git a/mysql-test/t/rpl_error_ignored_table-slave.opt b/mysql-test/t/rpl_error_ignored_table-slave.opt new file mode 100644 index 00000000000..544ecb2959b --- /dev/null +++ b/mysql-test/t/rpl_error_ignored_table-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t1
\ No newline at end of file diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test new file mode 100644 index 00000000000..caa289a184d --- /dev/null +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -0,0 +1,22 @@ +# Test for +# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave +# still checks that it has the same error as on the master. + +source include/master-slave.inc; +connection master; +create table t1 (a int primary key); +# generate an error that goes to the binlog +--error 1062; +insert into t1 values (1),(1); +save_master_pos; +connection slave; +# as the t1 table is ignored on the slave, the slave should be able to sync +sync_with_master; +show slave status; +# check that the table has been ignored, because otherwise the test is nonsense +show tables like 't1'; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test new file mode 100644 index 00000000000..4befe4024fc --- /dev/null +++ b/mysql-test/t/rpl_max_relay_size.test @@ -0,0 +1,81 @@ +# Test of options max_binlog_size and max_relay_log_size and +# how they act (if max_relay_log_size == 0, use max_binlog_size +# for relay logs too). +# Test of manual relay log rotation with FLUSH LOGS. + +source include/master-slave.inc; +connection slave; +stop slave; +connection master; +# Generate a big enough master's binlog to cause relay log rotations +create table t1 (a int); +let $1=800; +disable_query_log; +begin; +while ($1) +{ +# eval means expand $ expressions + eval insert into t1 values( $1 ); + dec $1; +} +enable_query_log; +drop table t1; +save_master_pos; +connection slave; +reset slave; +set global max_binlog_size=8192; +set global max_relay_log_size=8192-1; # mapped to 4096 +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; +stop slave; +reset slave; +set global max_relay_log_size=(5*4096); +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; +stop slave; +reset slave; +set global max_relay_log_size=0; +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; + +# Tests below are mainly to ensure that we have not coded with wrong assumptions + +stop slave; +reset slave; +# test of relay log rotation when the slave is stopped +# (to make sure it does not crash). +flush logs; +show slave status; + +reset slave; +start slave; +sync_with_master; +# test of relay log rotation when the slave is started +flush logs; +# We have now easy way to be sure that the SQL thread has now deleted the +# log we just closed. But a trick to achieve this is do an update on the master. +connection master; +create table t1 (a int); +save_master_pos; +connection slave; +sync_with_master; +show slave status; +# one more rotation, to be sure Relay_log_space is correctly updated +flush logs; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; +show slave status; + +connection master; +# test that the absence of relay logs does not make a master crash +flush logs; +show master status; diff --git a/mysql-test/t/rpl_rotate_logs-master.opt b/mysql-test/t/rpl_rotate_logs-master.opt index f27601e0d7d..ad2c6a647b5 100644 --- a/mysql-test/t/rpl_rotate_logs-master.opt +++ b/mysql-test/t/rpl_rotate_logs-master.opt @@ -1 +1 @@ --O max_binlog_size=2048 +-O max_binlog_size=4096 diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index fa35a1c6555..98a5c5b9f85 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -81,8 +81,11 @@ sub usage { die @_, $OPTIONS; } +# Do not initialize user or password options; that way, any user/password +# options specified in option files will be used. If no values are specified +# all, the defaults will be used (login name, no password). + my %opt = ( - user => scalar getpwuid($>), noindices => 0, allowold => 0, # for safety keepold => 0, @@ -165,6 +168,9 @@ $dsn = ";host=" . (defined($opt{host}) ? $opt{host} : "localhost"); $dsn .= ";port=$opt{port}" if $opt{port}; $dsn .= ";mysql_socket=$opt{socket}" if $opt{socket}; +# use mysql_read_default_group=mysqlhotcopy so that [client] and +# [mysqlhotcopy] groups will be read from standard options files. + my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=mysqlhotcopy", $opt{user}, $opt{password}, { @@ -654,9 +660,9 @@ sub safe_system print "Executing '@cmd'\n" if $opt{debug}; my $cp_status = system "@cmd > /dev/null"; if ($cp_status != 0) { - warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #' + warn "Executing command failed ($cp_status). Trying backtick execution...\n"; ## try something else - `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n"; + `@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; } } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 9857628ccc8..09119a4eb54 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3396,6 +3396,13 @@ ha_innobase::create( DBUG_ASSERT(thd != NULL); + if (form->fields > 1000) { + /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, + but we play safe here */ + + return(HA_ERR_TO_BIG_ROW); + } + /* Get the transaction associated with the current thd, or create one if not yet created */ diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 202cd90fd88..595123f7ac1 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -715,6 +715,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) } } enable_activate_all_index=1; + info(HA_STATUS_CONST); // Read new key info } else enable_activate_all_index=0; @@ -743,6 +744,7 @@ bool ha_myisam::activate_all_index(THD *thd) param.sort_buffer_length= thd->variables.myisam_sort_buff_size; param.tmpdir=mysql_tmpdir; error=repair(thd,param,0) != HA_ADMIN_OK; + info(HA_STATUS_CONST); thd->proc_info=save_proc_info; } else @@ -926,8 +928,9 @@ void ha_myisam::info(uint flag) ref_length=info.reflength; table->db_options_in_use = info.options; block_size=myisam_block_size; - table->keys_in_use&= info.key_map; - table->keys_for_keyread&= info.key_map; + table->keys_in_use= (set_bits(key_map, table->keys) & + (key_map) info.key_map); + table->keys_for_keyread= table->keys_in_use & ~table->read_only_keys; table->db_record_offset=info.record_offset; if (table->key_parts) memcpy((char*) table->key_info[0].rec_per_key, diff --git a/sql/log.cc b/sql/log.cc index 99bc6ee32b4..c24c2f2e39b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -133,11 +133,15 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) void MYSQL_LOG::init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg) + bool no_auto_events_arg, + ulong max_size_arg) { + DBUG_ENTER("MYSQL_LOG::init"); log_type = log_type_arg; io_cache_type = io_cache_type_arg; no_auto_events = no_auto_events_arg; + max_size=max_size_arg; + DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size)); if (!inited) { inited= 1; @@ -145,6 +149,7 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); (void) pthread_cond_init(&update_cond, 0); } + DBUG_VOID_RETURN; } @@ -165,7 +170,8 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg) + bool no_auto_events_arg, + ulong max_size) { char buff[512]; File file= -1, index_file_nr= -1; @@ -178,7 +184,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name)) no_rotate = 1; - init(log_type_arg,io_cache_type_arg,no_auto_events_arg); + init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size); if (!(name=my_strdup(log_name,MYF(MY_WME)))) goto err; @@ -577,7 +583,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) if (!thd->slave_thread) need_start_event=1; open(save_name, save_log_type, 0, index_file_name, - io_cache_type, no_auto_events); + io_cache_type, no_auto_events, max_size); my_free((gptr) save_name, MYF(0)); err: @@ -802,8 +808,12 @@ void MYSQL_LOG::new_file(bool need_lock) char new_name[FN_REFLEN], *new_name_ptr, *old_name; enum_log_type save_log_type; + DBUG_ENTER("MYSQL_LOG::new_file"); if (!is_open()) - return; // Should never happen + { + DBUG_PRINT("info",("log is closed")); + DBUG_VOID_RETURN; + } if (need_lock) { @@ -865,8 +875,11 @@ void MYSQL_LOG::new_file(bool need_lock) save_log_type=log_type; name=0; // Don't free name close(); + + // TODO: at this place is_open() will see the log closed, which is BUG#791. + open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, - no_auto_events); + no_auto_events, max_size); my_free(old_name,MYF(0)); end: @@ -875,6 +888,7 @@ end: pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_log); } + DBUG_VOID_RETURN; } @@ -882,7 +896,8 @@ bool MYSQL_LOG::append(Log_event* ev) { bool error = 0; pthread_mutex_lock(&LOCK_log); - + DBUG_ENTER("MYSQL_LOG::append"); + DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); /* Log_event::write() is smart enough to use my_b_write() or @@ -894,7 +909,8 @@ bool MYSQL_LOG::append(Log_event* ev) goto err; } bytes_written += ev->get_event_len(); - if ((uint) my_b_append_tell(&log_file) > max_binlog_size) + DBUG_PRINT("info",("max_size: %lu",max_size)); + if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); @@ -904,13 +920,14 @@ bool MYSQL_LOG::append(Log_event* ev) err: pthread_mutex_unlock(&LOCK_log); signal_update(); // Safe as we don't call close - return error; + DBUG_RETURN(error); } bool MYSQL_LOG::appendv(const char* buf, uint len,...) { bool error= 0; + DBUG_ENTER("MYSQL_LOG::appendv"); va_list(args); va_start(args,len); @@ -926,8 +943,8 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) } bytes_written += len; } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); - - if ((uint) my_b_append_tell(&log_file) > max_binlog_size) + DBUG_PRINT("info",("max_size: %lu",max_size)); + if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); @@ -938,7 +955,7 @@ err: pthread_mutex_unlock(&LOCK_log); if (!error) signal_update(); - return error; + DBUG_RETURN(error); } @@ -1188,8 +1205,9 @@ bool MYSQL_LOG::write(Log_event* event_info) called_handler_commit=1; } } - /* we wrote to the real log, check automatic rotation */ - should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size); + /* We wrote to the real log, check automatic rotation; */ + DBUG_PRINT("info",("max_size: %lu",max_size)); + should_rotate= (my_b_tell(file) >= (my_off_t) max_size); } error=0; @@ -1319,7 +1337,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) log_file.pos_in_file))) goto err; signal_update(); - if (my_b_tell(&log_file) >= (my_off_t) max_binlog_size) + DBUG_PRINT("info",("max_size: %lu",max_size)); + if (my_b_tell(&log_file) >= (my_off_t) max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); // inside mutex @@ -1563,6 +1582,24 @@ void MYSQL_LOG::close(bool exiting) DBUG_VOID_RETURN; } +void MYSQL_LOG::set_max_size(ulong max_size_arg) +{ + /* + We need to take locks, otherwise this may happen: + new_file() is called, calls open(old_max_size), then before open() starts, + set_max_size() sets max_size to max_size_arg, then open() starts and + uses the old_max_size argument, so max_size_arg has been overwritten and + it's like if the SET command was never run. + */ + if (is_open()) + { + pthread_mutex_lock(&LOCK_log); + pthread_mutex_lock(&LOCK_index); + max_size= max_size_arg; + pthread_mutex_unlock(&LOCK_index); + pthread_mutex_unlock(&LOCK_log); + } +} /* Check if a string is a valid number diff --git a/sql/log_event.cc b/sql/log_event.cc index 5f3d4263642..a6d2abbf894 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -69,7 +69,8 @@ static void pretty_print_str(FILE* file, char* str, int len) inline int ignored_error_code(int err_code) { - return use_slave_mask && bitmap_is_set(&slave_error_mask, err_code); + return ((err_code == ER_SLAVE_IGNORED_TABLE) || + (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code))); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ce23abb6b2c..0a4728ef325 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -618,8 +618,8 @@ bool fn_format_relative_to_data_home(my_string to, const char *name, bool open_log(MYSQL_LOG *log, const char *hostname, const char *opt_name, const char *extension, const char *index_file_name, - enum_log_type type, bool read_append = 0, - bool no_auto_events = 0); + enum_log_type type, bool read_append, + bool no_auto_events, ulong max_size); /* mysqld.cc */ void clear_error_message(THD *thd); @@ -666,7 +666,8 @@ extern ulong max_insert_delayed_threads, max_user_connections; extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode; extern ulong query_buff_size, thread_stack,thread_stack_min; extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit; -extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size; +extern ulong max_binlog_size, max_relay_log_size; +extern ulong rpl_recovery_rank, thread_cache_size; extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log; extern ulong specialflag, current_pid; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4f6f55bce0b..1ede1a87153 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -354,7 +354,7 @@ ulong table_cache_size, query_buff_size, slow_launch_time = 2L, slave_open_temp_tables=0, - open_files_limit=0, max_binlog_size; + open_files_limit=0, max_binlog_size, max_relay_log_size; ulong com_stat[(uint) SQLCOM_END], com_other; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; @@ -871,7 +871,6 @@ extern "C" void unireg_abort(int exit_code) sql_print_error("Aborting\n"); clean_up(1); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); - my_thread_end(); clean_up_mutexes(); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ @@ -1950,7 +1949,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, const char *opt_name, const char *extension, const char *index_file_name, enum_log_type type, bool read_append, - bool no_auto_events) + bool no_auto_events, ulong max_size) { char tmp[FN_REFLEN]; if (!opt_name || !opt_name[0]) @@ -1976,7 +1975,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, } return log->open(opt_name, type, 0, index_file_name, (read_append) ? SEQ_READ_APPEND : WRITE_CACHE, - no_auto_events); + no_auto_events, max_size); } @@ -2196,17 +2195,17 @@ int main(int argc, char **argv) /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, - LOG_NORMAL); + LOG_NORMAL, 0, 0, 0); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW); + NullS, LOG_NEW, 0, 0, 0); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - NullS, LOG_NORMAL); + NullS, LOG_NORMAL, 0, 0, 0); if (opt_error_log) { @@ -2321,7 +2320,7 @@ The server will not act as a slave."); if (opt_bin_log) { open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - opt_binlog_index_name,LOG_BIN); + opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size); using_update_log=1; } else if (opt_log_slave_updates) @@ -3156,8 +3155,8 @@ enum options { OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, - OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_SEEKS_FOR_KEY, - OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, + OPT_MAX_JOIN_SIZE, OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH, + OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, @@ -3598,17 +3597,17 @@ relay logs", {"skip-stack-trace", OPT_SKIP_STACK_TRACE, "Don't print a stack trace on failure", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Depricated option. Use --skip-symbolic-links instead", + {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-thread-priority", OPT_SKIP_PRIOR, "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, + {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, "The location and name of the file that remembers where the SQL replication \ thread is in the relay logs", (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, + {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "The location where the slave should put its temporary files when \ replicating a LOAD DATA INFILE command", (gptr*) &slave_load_tmpdir, (gptr*) &slave_load_tmpdir, 0, GET_STR_ALLOC, @@ -3630,7 +3629,7 @@ replicating a LOAD DATA INFILE command", #ifdef HAVE_OPENSSL #include "sslopt-longopts.h" #endif - {"temp-pool", OPT_TEMP_POOL, + {"temp-pool", OPT_TEMP_POOL, "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -3642,10 +3641,10 @@ replicating a LOAD DATA INFILE command", {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"use-symbolic-links", 's', "Enable symbolic link support. Depricated option; Use --symbolic-links instead", + {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; Use --symbolic-links instead", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, - {"--symbolic-links", 's', "Enable symbolic link support", + {"symbolic-links", 's', "Enable symbolic link support", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, {"user", 'u', "Run mysqld daemon as user", 0, 0, 0, GET_STR, REQUIRED_ARG, @@ -3809,9 +3808,11 @@ replicating a LOAD DATA INFILE command", (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, {"max_binlog_size", OPT_MAX_BINLOG_SIZE, - "Binary log will be rotated automatically when the size crosses the limit.", + "Binary log will be rotated automatically when the size exceeds this \ +value. Will also apply to relay logs if max_relay_log_size is 0. \ +The minimum value for this variable is 4096.", (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG, - REQUIRED_ARG, 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1, 0}, + REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0}, {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, @@ -3834,6 +3835,12 @@ replicating a LOAD DATA INFILE command", (gptr*) &global_system_variables.max_join_size, (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE, + "If non-zero: relay log will be rotated automatically when the size exceeds \ +this value; if zero (the default): when the size exceeds max_binlog_size. \ +0 expected, the minimum value for this variable is 4096.", + (gptr*) &max_relay_log_size, (gptr*) &max_relay_log_size, 0, GET_ULONG, + REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0}, { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY, "Limit assumed max number of seeks when looking up rows based on a key", (gptr*) &global_system_variables.max_seeks_for_key, diff --git a/sql/set_var.cc b/sql/set_var.cc index b66c410c6d5..b3238d1c0ec 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -84,6 +84,8 @@ static void fix_query_cache_size(THD *thd, enum_var_type type); static void fix_key_buffer_size(THD *thd, enum_var_type type); static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type); static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); +static void fix_max_binlog_size(THD *thd, enum_var_type type); +static void fix_max_relay_log_size(THD *thd, enum_var_type type); /* Variable definition list @@ -142,7 +144,8 @@ sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet", sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size", &max_binlog_cache_size); sys_var_long_ptr sys_max_binlog_size("max_binlog_size", - &max_binlog_size); + &max_binlog_size, + fix_max_binlog_size); sys_var_long_ptr sys_max_connections("max_connections", &max_connections); sys_var_long_ptr sys_max_connect_errors("max_connect_errors", @@ -161,6 +164,9 @@ sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif +sys_var_long_ptr sys_max_relay_log_size("max_relay_log_size", + &max_relay_log_size, + fix_max_relay_log_size); sys_var_thd_ulong sys_max_sort_length("max_sort_length", &SV::max_sort_length); sys_var_long_ptr sys_max_user_connections("max_user_connections", @@ -350,6 +356,7 @@ sys_var *sys_variables[]= &sys_max_delayed_threads, &sys_max_heap_table_size, &sys_max_join_size, + &sys_max_relay_log_size, &sys_max_seeks_for_key, &sys_max_sort_length, &sys_max_tmp_tables, @@ -495,6 +502,7 @@ struct show_var_st init_vars[]= { {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, + {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size, SHOW_SYS}, {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, @@ -697,6 +705,26 @@ void fix_delay_key_write(THD *thd, enum_var_type type) } } +void fix_max_binlog_size(THD *thd, enum_var_type type) +{ + DBUG_ENTER("fix_max_binlog_size"); + DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", + max_binlog_size, max_relay_log_size)); + mysql_bin_log.set_max_size(max_binlog_size); + if (!max_relay_log_size) + active_mi->rli.relay_log.set_max_size(max_binlog_size); + DBUG_VOID_RETURN; +} + +void fix_max_relay_log_size(THD *thd, enum_var_type type) +{ + DBUG_ENTER("fix_max_relay_log_size"); + DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", + max_binlog_size, max_relay_log_size)); + active_mi->rli.relay_log.set_max_size(max_relay_log_size ? + max_relay_log_size: max_binlog_size); + DBUG_VOID_RETURN; +} bool sys_var_long_ptr::update(THD *thd, set_var *var) { diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index f5e879679cc..72a593cf5f7 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -247,3 +247,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 13c061d50a1..f59abfeb6da 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -241,3 +241,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 45dbd663fec..974b4601ac8 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -249,3 +249,4 @@ "Foutieve toepassing/plaatsing van '%s'", "Deze versie van MySQL ondersteunt nog geen '%s'", "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index b7910bd07b3..3d7ca3b28df 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index c1b98d12b3a..38b45c1443b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -243,3 +243,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 242343769e6..df2be2803b4 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 10ec359abe8..cdeab579eca 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -241,3 +241,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 11534d9e11b..e3778aaac10 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f8c5dbcc836..85ea5c2e742 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index a82b0cdf18f..3be8058661a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -238,3 +238,4 @@ "Uso/posizione di '%s' sbagliato", "Questa versione di MySQL non supporta ancora '%s'", "Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 1b04ee5c2e4..f99d262a689 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index c57723f81e6..2a7e03b026d 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e331854ff68..e6ec84e98a0 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 817eec3058d..fe379261151 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index e5bede3b48c..a300dc1e2ab 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -242,3 +242,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index ea4f85f6b03..f9f37bfd924 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 7fc0c182f6a..bf1306cd332 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -242,3 +242,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index fc090205041..03964efb26b 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -240,3 +240,4 @@ "Неверное использование или в неверном месте указан '%s'", "Эта версия MySQL пока еще не поддерживает '%s'", "Получена неисправимая ошибка %d: '%-.128s' от головного сервера в процессе выборки данных из двоичного журнала", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 89a000db554..b9970465871 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -246,3 +246,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index c8e33325786..78b7e5ac907 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -239,3 +239,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 7ef663839c9..32eec834ed1 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -238,3 +238,4 @@ "Fel anvДnding/placering av '%s'", "Denna version av MySQL kan Дnnu inte utfЖra '%s'", "Fick fatalt fel %d: '%-.128s' frЕn master vid lДsning av binДrloggen" +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index a0a4a274d4b..c0931ab9f02 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -243,3 +243,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/slave.cc b/sql/slave.cc index aa9dd14b1c7..e0ca4f1ad7a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1205,10 +1205,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) /* The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. It is - notable that the last kilobytes of it (8 kB for example) may live in memory, - not on disk (depending on what the thread using it does). While this is - efficient, it has a side-effect one must know: - the size of the relay log on disk (displayed by 'ls -l' on Unix) can be a + notable that the last kilobytes of it (8 kB for example) may live in + memory, not on disk (depending on what the thread using it does). While + this is efficient, it has a side-effect one must know: + The size of the relay log on disk (displayed by 'ls -l' on Unix) can be a few kilobytes less than one would expect by doing SHOW SLAVE STATUS; this happens when only the IO thread is started (not the SQL thread). The "missing" kilobytes are in memory, are preserved during 'STOP SLAVE; START @@ -1221,21 +1221,32 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) See how 4 is less than 7811 and 8192 is less than 9744. - WARNING: this is risky because the slave can stay like this for a long time; - then if it has a power failure, master.info says the I/O thread has read - until 9744 while the relay-log contains only until 8192 (the in-memory part - from 8192 to 9744 has been lost), so the SQL slave thread will miss some - events, silently breaking replication. + WARNING: this is risky because the slave can stay like this for a long + time; then if it has a power failure, master.info says the I/O thread has + read until 9744 while the relay-log contains only until 8192 (the + in-memory part from 8192 to 9744 has been lost), so the SQL slave thread + will miss some events, silently breaking replication. Ideally we would like to flush master.info only when we know that the relay log has no in-memory tail. Note that the above problem may arise only when only the IO thread is started, which is unlikely. */ + /* + For the maximum log size, we choose max_relay_log_size if it is + non-zero, max_binlog_size otherwise. If later the user does SET + GLOBAL on one of these variables, fix_max_binlog_size and + fix_max_relay_log_size will reconsider the choice (for example + if the user changes max_relay_log_size to zero, we have to + switch to using max_binlog_size for the relay log) and update + rli->relay_log.max_size (and mysql_bin_log.max_size). + */ + if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin", opt_relaylog_index_name, LOG_BIN, 1 /* read_append cache */, - 1 /* no auto events */)) + 1 /* no auto events */, + max_relay_log_size ? max_relay_log_size : max_binlog_size)) { sql_print_error("Failed in open_log() called from init_relay_log_info()"); DBUG_RETURN(1); @@ -3421,6 +3432,48 @@ err: DBUG_RETURN(0); } +/* + Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation + because of size is simpler because when we do it we already have all relevant + locks; here we don't, so this function is mainly taking locks). + Returns nothing as we cannot catch any error (MYSQL_LOG::new_file() is void). +*/ + +void rotate_relay_log(MASTER_INFO* mi) +{ + DBUG_ENTER("rotate_relay_log"); + RELAY_LOG_INFO* rli= &mi->rli; + /* If this server is not a slave (or RESET SLAVE has just been run) */ + if (!rli->inited) + { + DBUG_PRINT("info", ("rli->inited == 0")); + DBUG_VOID_RETURN; + } + lock_slave_threads(mi); + pthread_mutex_lock(&rli->data_lock); + + /* If the relay log is closed, new_file() will do nothing. */ + rli->relay_log.new_file(1); + + /* + We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately + be counted, so imagine a succession of FLUSH LOGS and assume the slave + threads are started: + relay_log_space decreases by the size of the deleted relay log, but does + not increase, so flush-after-flush we may become negative, which is wrong. + Even if this will be corrected as soon as a query is replicated on the + slave (because the I/O thread will then call harvest_bytes_written() which + will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange + output in SHOW SLAVE STATUS meanwhile. So we harvest now. + If the log is closed, then this will just harvest the last writes, probably + 0 as they probably have been harvested. + */ + rli->relay_log.harvest_bytes_written(&rli->log_space_total); + pthread_mutex_unlock(&rli->data_lock); + unlock_slave_threads(mi); + DBUG_VOID_RETURN; +} + #ifdef __GNUC__ template class I_List_iterator<i_string>; diff --git a/sql/slave.h b/sql/slave.h index cae8c6ae241..842ddca75f4 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -402,6 +402,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos, int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, const char** errmsg); +void rotate_relay_log(MASTER_INFO* mi); extern "C" pthread_handler_decl(handle_slave_io,arg); extern "C" pthread_handler_decl(handle_slave_sql,arg); diff --git a/sql/sql_class.h b/sql/sql_class.h index d1b2ef82ccb..71b943b5d26 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -84,6 +84,17 @@ class MYSQL_LOG { bool no_rotate; bool need_start_event; bool no_auto_events; // for relay binlog + /* + The max size before rotation (usable only if log_type == LOG_BIN: binary + logs and relay logs). + For a binlog, max_size should be max_binlog_size. + For a relay log, it should be max_relay_log_size if this is non-zero, + max_binlog_size otherwise. + max_size is set in init(), and dynamically changed (when one does SET + GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and + fix_max_relay_log_size). + */ + ulong max_size; friend class Log_event; public: @@ -105,17 +116,18 @@ public: bytes_written=0; DBUG_VOID_RETURN; } + void set_max_size(ulong max_size_arg); void signal_update() { pthread_cond_broadcast(&update_cond);} void wait_for_update(THD* thd); void set_need_start_event() { need_start_event = 1; } void init(enum_log_type log_type_arg, - enum cache_type io_cache_type_arg = WRITE_CACHE, - bool no_auto_events_arg = 0); + enum cache_type io_cache_type_arg, + bool no_auto_events_arg, ulong max_size); void cleanup(); bool open(const char *log_name,enum_log_type log_type, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg); + bool no_auto_events_arg, ulong max_size); void new_file(bool need_lock= 1); bool write(THD *thd, enum enum_server_command command, const char *format,...); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index caa1e0e0312..45acbaaa7ef 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -145,7 +145,15 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, else { table->file->print_error(error,MYF(0)); - error=0; + /* + In < 4.0.14 we set the error number to 0 here, but that + was not sensible, because then MySQL would not roll back the + failed DELETE, and also wrote it to the binlog. For MyISAM + tables a DELETE probably never should fail (?), but for + InnoDB it can fail in a FOREIGN KEY error or an + out-of-tablespace error. + */ + error= 1; break; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 625957027af..70c0f772d7d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1324,7 +1324,11 @@ mysql_execute_command(void) given and the table list says the query should not be replicated */ if (table_rules_on && tables && !tables_ok(thd,tables)) + { + /* we warn the slave SQL thread */ + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); DBUG_VOID_RETURN; + } #ifndef TO_BE_DELETED /* This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 @@ -1339,13 +1343,7 @@ mysql_execute_command(void) #endif } - /* - Skip if we are in the slave thread, some table rules have been given - and the table list says the query should not be replicated - */ - if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) || - (table_rules_on && tables && thd->slave_thread && - !tables_ok(thd,tables))) + if (lex->select_lex.next && create_total_list(thd,lex,&tables)) DBUG_VOID_RETURN; /* @@ -2180,7 +2178,7 @@ mysql_execute_command(void) } if (check_access(thd,SELECT_ACL,db,&thd->col_access)) goto error; /* purecov: inspected */ - if (!thd->col_access && grant_option && check_grant_db(thd,db)) + if (!thd->col_access && check_grant_db(thd,db)) { net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, thd->priv_user, @@ -2330,7 +2328,10 @@ mysql_execute_command(void) if (thd->slave_thread && (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) + { + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; + } if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; @@ -2354,7 +2355,10 @@ mysql_execute_command(void) if (thd->slave_thread && (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) + { + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; + } if (check_access(thd,DROP_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) @@ -3574,10 +3578,18 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) } if (options & REFRESH_LOG) { + /* + Flush the normal query log, the update log, the binary log, the slow query + log, and the relay log (if it exists). + */ mysql_log.new_file(1); mysql_update_log.new_file(1); mysql_bin_log.new_file(1); mysql_slow_log.new_file(1); + LOCK_ACTIVE_MI; + rotate_relay_log(active_mi); + UNLOCK_ACTIVE_MI; + if (ha_flush_logs()) result=1; if (flush_error_log()) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7176337dbfd..80e329a7f03 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1655,17 +1655,17 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, { Item_func *arg0=(Item_func *)(func->arguments()[0]), *arg1=(Item_func *)(func->arguments()[1]); - if ((functype == Item_func::GE_FUNC || - functype == Item_func::GT_FUNC) && - arg0->type() == Item::FUNC_ITEM && - arg0->functype() == Item_func::FT_FUNC && - arg1->const_item() && arg1->val()>0) + if (arg1->const_item() && + ((functype == Item_func::GE_FUNC && arg1->val()> 0) || + (functype == Item_func::GT_FUNC && arg1->val()>=0)) && + arg0->type() == Item::FUNC_ITEM && + arg0->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg0; - else if ((functype == Item_func::LE_FUNC || - functype == Item_func::LT_FUNC) && + else if (arg0->const_item() && + ((functype == Item_func::LE_FUNC && arg0->val()> 0) || + (functype == Item_func::LT_FUNC && arg0->val()>=0)) && arg1->type() == Item::FUNC_ITEM && - arg1->functype() == Item_func::FT_FUNC && - arg0->const_item() && arg0->val()>0) + arg1->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg1; } } @@ -1676,26 +1676,13 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) { Item *item; - /* - I'm (Sergei) too lazy to implement proper recursive descent here, - and anyway, nobody will use such a stupid queries - that will require it :-) - May be later... - */ while ((item=li++)) - { - if (item->type() == Item::FUNC_ITEM && - ((Item_func *)item)->functype() == Item_func::FT_FUNC) - { - cond_func=(Item_func_match *)item; - break; - } - } + add_ft_keys(keyuse_array,stat,item,usable_tables); } } - if ((!cond_func || cond_func->key == NO_SUCH_KEY) || - (!(usable_tables & cond_func->table->map))) + if (!cond_func || cond_func->key == NO_SUCH_KEY || + !(usable_tables & cond_func->table->map)) return; KEYUSE keyuse; @@ -1707,7 +1694,6 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); } - static int sort_keyuse(KEYUSE *a,KEYUSE *b) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5a53ba30631..cf430aec35d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -918,7 +918,8 @@ mysql_rename_table(enum db_type base, wait_while_table_is_used() thd Thread handler table Table to remove from cache - + function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted + HA_EXTRA_FORCE_REOPEN if table is not be used NOTES When returning, the table will be unusable for other threads until the table is closed. @@ -928,13 +929,14 @@ mysql_rename_table(enum db_type base, Win32 clients must also have a WRITE LOCK on the table ! */ -static void wait_while_table_is_used(THD *thd,TABLE *table) +static void wait_while_table_is_used(THD *thd,TABLE *table, + enum ha_extra_function function) { DBUG_PRINT("enter",("table: %s", table->real_name)); DBUG_ENTER("wait_while_table_is_used"); safe_mutex_assert_owner(&LOCK_open); - VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files + VOID(table->file->extra(function)); /* Mark all tables that are in use as 'old' */ mysql_lock_abort(thd, table); // end threads waiting on lock @@ -970,7 +972,7 @@ static bool close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - wait_while_table_is_used(thd,table); + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { @@ -1529,14 +1531,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, break; case ENABLE: VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); error= table->file->activate_all_index(thd); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); table->file->deactivate_non_unique_index(HA_POS_ERROR); /* COND_refresh will be signaled in close_thread_tables() */ diff --git a/sql/table.cc b/sql/table.cc index a26ab89bd97..e938757cf6c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -422,7 +422,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* This has to be done after the above fulltext correction */ index_flags=outparam->file->index_flags(key); if (!(index_flags & HA_KEY_READ_ONLY)) + { + outparam->read_only_keys|= ((key_map) 1 << key); outparam->keys_for_keyread&= ~((key_map) 1 << key); + } if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) { diff --git a/sql/table.h b/sql/table.h index b6935ea6a32..57be97ffbda 100644 --- a/sql/table.h +++ b/sql/table.h @@ -62,7 +62,7 @@ struct st_table { uint uniques; uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ - key_map keys_in_use, keys_for_keyread; + key_map keys_in_use, keys_for_keyread, read_only_keys; key_map quick_keys, used_keys, keys_in_use_for_query; KEY *key_info; /* data of keys in database */ TYPELIB keynames; /* Pointers to keynames */ |