summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2001-12-15 05:12:21 +0200
committerunknown <monty@hundin.mysql.fi>2001-12-15 05:12:21 +0200
commit63e4dec2446382bf0331d2c483daee665064b925 (patch)
tree5b07ad850f8dba78d186135337dd5a151d18a2b8
parent6a5f89c9b190b0f26fc0cb12595126cba2659f32 (diff)
parentf8b4629cf728072b230159718994f585145b4ce2 (diff)
downloadmariadb-git-63e4dec2446382bf0331d2c483daee665064b925.tar.gz
Merge with 3.23.47
extra/resolve_stack_dump.c: Auto merged include/my_bitmap.h: Auto merged innobase/buf/buf0buf.c: Auto merged innobase/dict/dict0crea.c: Auto merged mysql-test/t/rpl_get_lock.test: Auto merged
-rw-r--r--Docs/manual.texi35
-rw-r--r--extra/mysql_install.c62
-rw-r--r--extra/resolve_stack_dump.c3
-rw-r--r--include/my_bitmap.h12
-rw-r--r--innobase/buf/buf0buf.c3
-rw-r--r--innobase/dict/dict0crea.c5
-rw-r--r--innobase/include/rem0rec.ic14
-rw-r--r--mysql-test/r/rpl_skip_error.result4
-rw-r--r--mysql-test/t/rpl_get_lock.test2
-rw-r--r--mysql-test/t/rpl_skip_error-slave.opt1
-rw-r--r--mysql-test/t/rpl_skip_error.test15
-rw-r--r--mysys/my_bitmap.c59
-rw-r--r--sql/mysqld.cc11
-rw-r--r--sql/slave.cc39
-rw-r--r--sql/slave.h5
15 files changed, 252 insertions, 18 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi
index cf4b065a21a..4d059bd496a 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -23452,6 +23452,33 @@ Updates to a database with a different name than the original
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}.
@@ -48035,22 +48062,26 @@ not yet 100% confident in this code.
@appendixsubsec Changes in release 3.23.47
@itemize @bullet
@item
+Added @code{slave-skip-errors} option
+@item
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
now much longer).
@item
-Fix default values for InnoDB tables.
+Fixed default values for InnoDB tables.
@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.
@item
diff --git a/extra/mysql_install.c b/extra/mysql_install.c
new file mode 100644
index 00000000000..dfd71895647
--- /dev/null
+++ b/extra/mysql_install.c
@@ -0,0 +1,62 @@
+/* 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@mysql.com>
+ */
+
+#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");
+}
+
+
+
+
+
+
diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c
index d79fb1b6e5d..6c2ddf66027 100644
--- a/extra/resolve_stack_dump.c
+++ b/extra/resolve_stack_dump.c
@@ -74,7 +74,8 @@ static void usage()
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\
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 11df10f26a1..ca0037addfb 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -25,6 +25,12 @@ typedef struct st_bitmap
{
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
@@ -33,10 +39,14 @@ typedef struct st_bitmap
#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
}
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index b9dfa3df82a..adb61bfbb56 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -1158,6 +1158,9 @@ buf_page_init(
block->n_hash_helps = 0;
block->is_hashed = FALSE;
+ block->n_fields = 1;
+ block->n_bytes = 0;
+ block->side = BTR_SEARCH_LEFT_SIDE;
block->file_page_was_freed = FALSE;
}
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 906683ca643..7b9255b4e27 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -1234,9 +1234,12 @@ loop:
que_graph_free(graph);
if (error != DB_SUCCESS) {
+ fprintf(stderr,
+ "InnoDB: foreign constraint creation failed;\n"
+ "InnoDB: internal error number %lu\n", error);
+
ut_a(error == DB_OUT_OF_FILE_SPACE);
- fprintf(stderr, "InnoDB: foreign constraint creation failed\n");
fprintf(stderr, "InnoDB: tablespace is full\n");
trx_general_rollback_for_mysql(trx, FALSE, NULL);
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 1e9ecb47e2e..6b96e3056fa 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -947,7 +947,8 @@ rec_get_converted_size(
}
/****************************************************************
-Folds a prefix of a physical record to a ulint. */
+Folds a prefix of a physical record to a ulint. Folds only existing fields,
+that is, checks that we do not run out of the record. */
UNIV_INLINE
ulint
rec_fold(
@@ -963,6 +964,7 @@ rec_fold(
byte* data;
ulint len;
ulint fold;
+ ulint n_fields_rec;
ut_ad(rec_validate(rec));
ut_ad(n_fields <= rec_get_n_fields(rec));
@@ -971,6 +973,16 @@ rec_fold(
/* Only the page supremum and infimum records have 1 field: */
ut_ad(rec_get_n_fields(rec) > 1);
+ n_fields_rec = rec_get_n_fields(rec);
+
+ if (n_fields > n_fields_rec) {
+ n_fields = n_fields_rec;
+ }
+
+ if (n_fields == n_fields_rec) {
+ n_bytes = 0;
+ }
+
fold = ut_fold_dulint(tree_id);
for (i = 0; i < n_fields; i++) {
diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result
new file mode 100644
index 00000000000..f85b057eefa
--- /dev/null
+++ b/mysql-test/r/rpl_skip_error.result
@@ -0,0 +1,4 @@
+n
+1
+2
+3
diff --git a/mysql-test/t/rpl_get_lock.test b/mysql-test/t/rpl_get_lock.test
index 45adf99ed21..93f911e01d5 100644
--- a/mysql-test/t/rpl_get_lock.test
+++ b/mysql-test/t/rpl_get_lock.test
@@ -4,6 +4,8 @@ create table t1(n int);
insert into t1 values(get_lock("lock",2));
dirty_close master;
connection master1;
+select get_lock("lock",2);
+select release_lock("lock");
save_master_pos;
connection slave;
sync_with_master;
diff --git a/mysql-test/t/rpl_skip_error-slave.opt b/mysql-test/t/rpl_skip_error-slave.opt
new file mode 100644
index 00000000000..f6f258f799f
--- /dev/null
+++ b/mysql-test/t/rpl_skip_error-slave.opt
@@ -0,0 +1 @@
+--slave-skip-error=1053,1062
diff --git a/mysql-test/t/rpl_skip_error.test b/mysql-test/t/rpl_skip_error.test
new file mode 100644
index 00000000000..3303b45c1ca
--- /dev/null
+++ b/mysql-test/t/rpl_skip_error.test
@@ -0,0 +1,15 @@
+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;
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index bdaa2c37a2c..7fc094bdb71 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -25,15 +25,33 @@
#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
- pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
+ if ((map->thread_safe = thread_safe))
+ pthread_mutex_init(&map->mutex, MY_MUTEX_INIT_FAST);
#endif
map->bitmap_size=bitmap_size;
return 0;
@@ -46,7 +64,8 @@ void bitmap_free(MY_BITMAP *map)
my_free((char*) map->bitmap, MYF(0));
map->bitmap=0;
#ifdef THREAD
- pthread_mutex_destroy(&map->mutex);
+ if (map->thread_safe)
+ pthread_mutex_destroy(&map->mutex);
#endif
}
}
@@ -55,9 +74,9 @@ void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
{
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);
}
}
@@ -69,7 +88,7 @@ uint bitmap_set_next(MY_BITMAP *map)
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)
@@ -87,7 +106,7 @@ uint bitmap_set_next(MY_BITMAP *map)
break; /* Found bit */
}
}
- pthread_mutex_unlock(&map->mutex);
+ bitmap_unlock(map);
return bit_found;
}
@@ -96,8 +115,30 @@ void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
{
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);
+}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5437db767a3..1294f379d2b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -735,6 +735,8 @@ void clean_up(bool print_message)
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();
query_cache.resize(0);
@@ -1801,7 +1803,7 @@ int main(int argc, char **argv)
#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);
/*
@@ -2674,7 +2676,7 @@ enum options {
OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
- OPT_DES_KEY_FILE
+ OPT_DES_KEY_FILE, OPT_SLAVE_SKIP_ERRORS
};
static struct option long_options[] = {
@@ -2824,6 +2826,8 @@ static struct option long_options[] = {
{"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS},
{"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR},
{"slave-load-tmpdir", required_argument, 0, (int) OPT_SLAVE_LOAD_TMPDIR},
+ {"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},
@@ -3586,6 +3590,9 @@ static void get_options(int argc,char **argv)
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)
safemalloc_mem_limit = atoi(optarg);
diff --git a/sql/slave.cc b/sql/slave.cc
index 7a603ec0827..3272344e478 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -29,6 +29,8 @@ volatile bool slave_running = 0;
char* slave_load_tmpdir = 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;
@@ -81,6 +83,37 @@ static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
}
+/* called from get_options() in mysqld.cc on start-up */
+void init_slave_skip_errors(char* arg)
+{
+ char* p;
+ 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 */;
+ if (!my_casecmp(arg,"all",3))
+ {
+ bitmap_set_all(&slave_error_mask);
+ return;
+ }
+ for (p= arg ; *p; )
+ {
+ long err_code;
+ if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
+ break;
+ if (err_code < MAX_SLAVE_ERROR)
+ bitmap_set_bit(&slave_error_mask,(uint)err_code);
+ while (!isdigit(*p) && *p)
+ p++;
+ }
+}
+
+
void init_table_rule_hash(HASH* h, bool* h_inited)
{
hash_init(h, TABLE_RULE_HASH_SIZE,0,0,
@@ -1004,6 +1037,12 @@ point. If you are sure that your master is ok, run this query manually on the\
}
}
+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)
{
const char *error_msg;
diff --git a/sql/slave.h b/sql/slave.h
index 705572bd7a8..887236b885f 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -3,8 +3,11 @@
#include "mysql.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;
extern char* slave_load_tmpdir;
typedef struct st_master_info
@@ -104,11 +107,11 @@ int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
+void init_slave_skip_errors(char* arg);
char* rewrite_db(char* db);
int check_expected_error(THD* thd, int error_code);
void skip_load_data_infile(NET* net);
void slave_print_error(int err_code, const char* msg, ...);
-
void end_slave(); // clean up
int init_master_info(MASTER_INFO* mi);
void end_master_info(MASTER_INFO* mi);