Below is the list of changes that have just been commited into a local
3.23. repository of sasha. When sasha does a push, they will be
propogaged to the main repository and within 24 hours after the push into
the public repository. For information on how to access
the public repository see
http://www.mysql.com/doc/I/n/Installing_source_tree.html
ChangeSet@stripped, 2001-12-12 18:55:33-07:00, sasha@stripped
slave-skip-errors
added extra/mysql_install.c - will work on it in 4.0, but it does not hurt
to have it sit in 3.23 tree for now since it will eventually be backported
to 3.23 anyway
extra/mysql_install.c
1.1 01/12/12 18:55:33 sasha@stripped +62 -0
mysql-test/r/rpl_skip_error.result
1.1 01/12/12 18:55:33 sasha@stripped +4 -0
mysql-test/t/rpl_skip_error-slave.opt
1.1 01/12/12 18:55:33 sasha@stripped +1 -0
mysql-test/t/rpl_skip_error.test
1.1 01/12/12 18:55:33 sasha@stripped +15 -0
extra/mysql_install.c
1.0 01/12/12 18:55:33 sasha@stripped +0 -0
BitKeeper file /reiser-data/mysql/extra/mysql_install.c
mysql-test/r/rpl_skip_error.result
1.0 01/12/12 18:55:33 sasha@stripped +0 -0
BitKeeper file /reiser-data/mysql/mysql-test/r/rpl_skip_error.result
mysql-test/t/rpl_skip_error-slave.opt
1.0 01/12/12 18:55:33 sasha@stripped +0 -0
BitKeeper file /reiser-data/mysql/mysql-test/t/rpl_skip_error-slave.opt
mysql-test/t/rpl_skip_error.test
1.0 01/12/12 18:55:33 sasha@stripped +0 -0
BitKeeper file /reiser-data/mysql/mysql-test/t/rpl_skip_error.test
sql/slave.cc
1.119 01/12/12 18:55:33 sasha@stripped +57 -3
slave-skip-errors
sql/slave.h
1.19 01/12/12 18:55:33 sasha@stripped +4 -0
slave skip errors
Docs/manual.texi
1.747 01/12/12 18:55:32 sasha@stripped +32 -1
documented slave-skip-errors
updated change history
extra/resolve_stack_dump.c
1.6 01/12/12 18:55:32 sasha@stripped +2 -1
fixed wrong help message
include/my_bitmap.h
1.4 01/12/12 18:55:32 sasha@stripped +10 -1
bitmap code updates
mysql-test/r/rpl_get_lock.result
1.2 01/12/12 18:55:32 sasha@stripped +2 -0
test for a possible bug in release_lock() replication
mysql-test/t/rpl_get_lock.test
1.2 01/12/12 18:55:32 sasha@stripped +1 -0
test for possible bug in release_lock replication
mysys/my_bitmap.c
1.7 01/12/12 18:55:32 sasha@stripped +45 -7
bitmap code updates/clean-up
sql/mysqld.cc
1.220 01/12/12 18:55:32 sasha@stripped +10 -2
slave-skip-errors
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: sasha
# Host: mysql.sashanet.com
# Root: /reiser-data/mysql
--- 1.746/Docs/manual.texi Mon Dec 10 08:51:06 2001
+++ 1.747/Docs/manual.texi Wed Dec 12 18:55:32 2001
@@ -23738,6 +23738,33 @@
Example: @code{replicate-rewrite-db=master_db_name->slave_db_name}.
+@item @code{slave-skip-errors=err_code1,err_code2,..} @tab
+Available only in 3.23.47 and later. Tells the slave thread to continue
+replication when a query returns an error from the provided
+list. Normally, replication will discontinue when an error is
+encountered giving the user a chance to resolve the inconsistency in the
+data manually. Do not use this option unless you fully understand why
+you are getting the errors. If there are no bugs in your
+replication setup and client programs, and no bugs in MySQL itself, you
+should never get an abort with error.Indiscriminate use of this option
+will result in slaves being hopelessly out of sync with the master and
+you having no idea how the problem happened.
+
+For error codes, you should use the numbers provided by the error message in
+your slave error log and in the output of @code{SHOW SLAVE STATUS}. Full list
+of error messages can be found in the source distribution in
+@code{Docs/mysqld_error.txt}.
+
+You can ( but should not) also use a very non-recommended value of @code{all}
+which will ignore all error messages and keep barging along regardless.
+Needless to say, if you use it, we make no promises regarding your data
+integrity. Please do not complain if your data on the slave is not anywhere
+close to what it is on the master in this case - you have been warned.
+
+Example:
+
+@code{slave-skip-errors=1062,1053} or @code{slave-skip-errors=all}
+
@item @code{skip-slave-start} @tab
Tells the slave server not to start the slave on the startup. The user
can start it later with @code{SLAVE START}.
@@ -46839,16 +46866,20 @@
@appendixsubsec Changes in release 3.23.47
@itemize @bullet
@item
+Added @code{slave-skip-errors} option
+@item
Fixed that @code{GROUP BY expr DESC} works.
@item
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
@item
-@code{mysqlconfig} now also work with binary (relocated) distributions.
+@code{mysql_config} now also work with binary (relocated) distributions.
@end itemize
@node News-3.23.46, News-3.23.45, News-3.23.47, News-3.23.x
@appendixsubsec Changes in release 3.23.46
@itemize @bullet
+@item
+Fixed problem with aliased temporary tables replication
@item
InnoDB and BDB tables will now use index when doing an @code{ORDER BY}
on the whole table.
--- 1.219/sql/mysqld.cc Sun Nov 25 17:16:37 2001
+++ 1.220/sql/mysqld.cc Wed Dec 12 18:55:32 2001
@@ -707,6 +707,8 @@
DBUG_PRINT("exit",("clean_up"));
if (cleanup_done++)
return; /* purecov: inspected */
+ if (use_slave_mask)
+ bitmap_free(&slave_error_mask);
acl_free(1);
grant_free();
sql_cache_free();
@@ -1757,7 +1759,7 @@
#endif
select_thread=pthread_self();
select_thread_in_use=1;
- if (use_temp_pool && bitmap_init(&temp_pool,1024))
+ if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
unireg_abort(1);
/*
@@ -2600,7 +2602,8 @@
OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
- OPT_SAFE_USER_CREATE, OPT_SQL_MODE
+ OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
+ OPT_SLAVE_SKIP_ERRORS
};
static struct option long_options[] = {
@@ -2735,6 +2738,8 @@
{"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE},
{"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
{"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
+ {"slave-skip-errors", required_argument,0,
+ (int) OPT_SLAVE_SKIP_ERRORS},
{"socket", required_argument, 0, (int) OPT_SOCKET},
{"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME},
{"sql-mode", required_argument, 0, (int) OPT_SQL_MODE},
@@ -3395,6 +3400,9 @@
break;
case 'P':
mysql_port= (unsigned int) atoi(optarg);
+ break;
+ case OPT_SLAVE_SKIP_ERRORS:
+ init_slave_skip_errors(optarg);
break;
case OPT_SAFEMALLOC_MEM_LIMIT:
#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
--- 1.118/sql/slave.cc Tue Nov 27 18:20:24 2001
+++ 1.119/sql/slave.cc Wed Dec 12 18:55:33 2001
@@ -29,6 +29,8 @@
volatile bool slave_running = 0;
pthread_t slave_real_id;
MASTER_INFO glob_mi;
+MY_BITMAP slave_error_mask;
+bool use_slave_mask = 0;
HASH replicate_do_table, replicate_ignore_table;
DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
bool do_table_inited = 0, ignore_table_inited = 0;
@@ -73,6 +75,50 @@
return (byte*)e->db;
}
+/* called from get_options() in mysqld.cc on start-up */
+void init_slave_skip_errors(char* arg)
+{
+ char* p,*end;
+ int err_code = 0;
+ my_bool last_was_digit = 0;
+ if (bitmap_init(&slave_error_mask,MAX_SLAVE_ERROR,0))
+ {
+ fprintf(stderr, "Badly out of memory, please check your system status\n");
+ exit(1);
+ }
+ use_slave_mask = 1;
+ for (;isspace(*arg);++arg)
+ /* empty */;
+ /* force first three chars to lower case */
+ for (p = arg, end = arg + 3; *p && p < end; ++p)
+ *p = tolower(*p);
+ if (!memcmp(arg,"all",3))
+ {
+ bitmap_set_all(&slave_error_mask);
+ return;
+ }
+ for (p = arg, end = strend(arg); p < end; ++p)
+ {
+ int digit = *p - '0';
+ if (digit >= 0 && digit < 10) /* found real digit */
+ {
+ err_code = err_code * 10 + digit;
+ last_was_digit = 1;
+ }
+ else /* delimiter */
+ {
+ if (last_was_digit)
+ {
+ if (err_code < MAX_SLAVE_ERROR)
+ {
+ bitmap_set_bit(&slave_error_mask,err_code);
+ }
+ err_code = 0;
+ last_was_digit = 0;
+ }
+ }
+ }
+}
void init_table_rule_hash(HASH* h, bool* h_inited)
{
@@ -869,6 +915,11 @@
}
}
+inline int ignored_error_code(int err_code)
+{
+ return use_slave_mask && bitmap_is_set(&slave_error_mask, err_code);
+}
+
static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
{
Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1,
@@ -925,11 +976,13 @@
// sanity check to make sure the master did not get a really bad
// error on the query
- if (!check_expected_error(thd, (expected_error = qev->error_code)))
+ if (ignored_error_code((expected_error=qev->error_code)) ||
+ !check_expected_error(thd, expected_error))
{
mysql_parse(thd, thd->query, q_len);
if (expected_error !=
- (actual_error = thd->net.last_errno) && expected_error)
+ (actual_error = thd->net.last_errno) && expected_error &&
+ !ignored_error_code(actual_error))
{
const char* errmsg = "Slave: did not get the expected error\
running query from master - expected: '%s' (%d), got '%s' (%d)";
@@ -939,7 +992,8 @@
actual_error);
thd->query_error = 1;
}
- else if (expected_error == actual_error)
+ else if (expected_error == actual_error ||
+ ignored_error_code(actual_error))
{
thd->query_error = 0;
*last_slave_error = 0;
--- 1.3/include/my_bitmap.h Wed Feb 7 14:27:18 2001
+++ 1.4/include/my_bitmap.h Wed Dec 12 18:55:32 2001
@@ -26,6 +26,11 @@
{
uchar *bitmap;
uint bitmap_size;
+ my_bool thread_safe; /* set if several threads access the bitmap */
+ /* mutex will be acquired for the duration of each bitmap operation if
+ thread_safe flag is set. Otherwise, we optimize by not acquiring the
+ mutex
+ */
#ifdef THREAD
pthread_mutex_t mutex;
#endif
@@ -34,10 +39,14 @@
#ifdef __cplusplus
extern "C" {
#endif
- extern my_bool bitmap_init(MY_BITMAP *bitmap, uint bitmap_size);
+ extern my_bool bitmap_init(MY_BITMAP *bitmap, uint bitmap_size,
+ my_bool thread_safe);
extern void bitmap_free(MY_BITMAP *bitmap);
extern void bitmap_set_bit(MY_BITMAP *bitmap, uint bitmap_bit);
extern uint bitmap_set_next(MY_BITMAP *bitmap);
+ extern void bitmap_set_all(MY_BITMAP* bitmap);
+ extern my_bool bitmap_is_set(MY_BITMAP* bitmap, uint bitmap_bit);
+ extern void bitmap_clear_all(MY_BITMAP* bitmap);
extern void bitmap_clear_bit(MY_BITMAP *bitmap, uint bitmap_bit);
#ifdef __cplusplus
}
--- 1.6/mysys/my_bitmap.c Sat Mar 24 11:15:08 2001
+++ 1.7/mysys/my_bitmap.c Wed Dec 12 18:55:32 2001
@@ -26,14 +26,32 @@
#include "mysys_priv.h"
#include <my_bitmap.h>
#include <assert.h>
+#include <string.h>
-my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size)
+inline void bitmap_lock(MY_BITMAP* map)
+{
+#ifdef THREAD
+ if (map->thread_safe)
+ pthread_mutex_lock(&map->mutex);
+#endif
+}
+
+inline void bitmap_unlock(MY_BITMAP* map)
+{
+#ifdef THREAD
+ if (map->thread_safe)
+ pthread_mutex_unlock(&map->mutex);
+#endif
+}
+
+my_bool bitmap_init(MY_BITMAP *map, uint bitmap_size, my_bool thread_safe)
{
if (!(map->bitmap=(uchar*) my_malloc((bitmap_size+7)/8,
MYF(MY_WME | MY_ZEROFILL))))
return 1;
dbug_assert(bitmap_size != ~(uint) 0);
#ifdef THREAD
+ map->thread_safe = thread_safe;
pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
#endif
map->bitmap_size=bitmap_size;
@@ -56,9 +74,9 @@
{
if (bitmap_bit < map->bitmap_size)
{
- pthread_mutex_lock(&map->mutex);
+ bitmap_lock(map);
map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7));
- pthread_mutex_unlock(&map->mutex);
+ bitmap_unlock(map);
}
}
@@ -70,7 +88,7 @@
uint bitmap_size=map->bitmap_size;
uint i;
- pthread_mutex_lock(&map->mutex);
+ bitmap_lock(map);
for (i=0; i < bitmap_size ; i++, bitmap++)
{
if (*bitmap != 0xff)
@@ -88,7 +106,7 @@
break; /* Found bit */
}
}
- pthread_mutex_unlock(&map->mutex);
+ bitmap_unlock(map);
return bit_found;
}
@@ -97,9 +115,29 @@
{
if (bitmap_bit < map->bitmap_size)
{
- pthread_mutex_lock(&map->mutex);
+ bitmap_lock(map);
map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7));
- pthread_mutex_unlock(&map->mutex);
+ bitmap_unlock(map);
}
}
+void bitmap_set_all(MY_BITMAP* map)
+{
+ bitmap_lock(map);
+ memset(map->bitmap, 0xff, (map->bitmap_size+7)/8);
+ bitmap_unlock(map);
+}
+
+my_bool bitmap_is_set(MY_BITMAP* map, uint bitmap_bit)
+{
+ return (bitmap_bit < map->bitmap_size) ?
+ (map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7))) :
+ 0;
+}
+
+void bitmap_clear_all(MY_BITMAP* map)
+{
+ bitmap_lock(map);
+ bzero(map->bitmap,(map->bitmap_size+7)/8);
+ bitmap_unlock(map);
+}
--- 1.18/sql/slave.h Wed Oct 3 07:27:20 2001
+++ 1.19/sql/slave.h Wed Dec 12 18:55:33 2001
@@ -2,8 +2,11 @@
#define SLAVE_H
#define SLAVE_NET_TIMEOUT 3600
+#define MAX_SLAVE_ERROR 2000
extern ulong slave_net_timeout, master_retry_count;
+extern MY_BITMAP slave_error_mask;
+extern bool use_slave_mask;
typedef struct st_master_info
{
@@ -89,6 +92,7 @@
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
+void init_slave_skip_errors(char* arg);
void end_slave(); // clean up
int init_master_info(MASTER_INFO* mi);
--- New file ---
+++ extra/mysql_install.c 01/12/12 18:55:33
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/* Install or upgrade MySQL server. By Sasha Pachev <sasha@stripped>
*/
#define INSTALL_VERSION "1.0"
#define DONT_USE_RAID
#include <global.h>
#include <m_ctype.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql_version.h>
#include <errno.h>
#include <getopt.h>
struct option long_options[] =
{
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{0, 0,0,0}
};
static void print_version(void)
{
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,INSTALL_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
}
static void usage()
{
print_version();
printf("MySQL AB, by Sasha Pachev\n");
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Install or upgrade MySQL server.\n\n");
printf("Usage: %s [OPTIONS] \n", my_progname);
printf("\n\
-?, --help Display this help and exit.\n\
-h, --host=... Connect to host.\n\
-V, --version Output version information and exit.\n");
}
--- 1.5/extra/resolve_stack_dump.c Wed Apr 25 13:44:26 2001
+++ 1.6/extra/resolve_stack_dump.c Wed Dec 12 18:55:32 2001
@@ -75,7 +75,8 @@
printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n", my_progname);
printf("\n\
-?, --help Display this help and exit.\n\
- -h, --host=... Connect to host.\n\
+ -s, --symbols-file=... Use specified symbols file.\n\
+ -n, --numeric-dump-file=... Read the dump from specified file.\n\
-V, --version Output version information and exit.\n");
printf("\n\
The symbols-file should include the output from: 'nm --numeric-sort mysqld'.\n\
--- 1.1/mysql-test/r/rpl_get_lock.result Fri Aug 31 15:55:49 2001
+++ 1.2/mysql-test/r/rpl_get_lock.result Wed Dec 12 18:55:32 2001
@@ -1,3 +1,5 @@
+release_lock("lock")
+0
get_lock("lock",3)
1
n
--- New file ---
+++ mysql-test/r/rpl_skip_error.result 01/12/12 18:55:33
n
1
2
3
--- 1.1/mysql-test/t/rpl_get_lock.test Fri Aug 31 15:55:49 2001
+++ 1.2/mysql-test/t/rpl_get_lock.test Wed Dec 12 18:55:32 2001
@@ -4,6 +4,7 @@
insert into t1 values(get_lock("lock",2));
dirty_close master;
connection master1;
+select release_lock("lock");
save_master_pos;
connection slave;
sync_with_master;
--- New file ---
+++ mysql-test/t/rpl_skip_error-slave.opt 01/12/12 18:55:33
--slave-skip-error=1053,1062
--- New file ---
+++ mysql-test/t/rpl_skip_error.test 01/12/12 18:55:33
source include/master-slave.inc;
connection master;
drop table if exists t1;
create table t1 (n int not null primary key);
save_master_pos;
connection slave;
sync_with_master;
insert into t1 values (1);
connection master;
insert into t1 values (1);
insert into t1 values (2),(3);
save_master_pos;
connection slave;
sync_with_master;
select * from t1;