Commit 18149be5 authored by igor@rurik.mysql.com's avatar igor@rurik.mysql.com

Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  rurik.mysql.com:/home/igor/mysql-5.1
parents a6be98b8 778e362b
INCLUDE_DIRECTORIES(../mySTL include) INCLUDE_DIRECTORIES(../mySTL include)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /GX-")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GX-")
ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp
src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp
src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp
......
...@@ -284,7 +284,7 @@ our $opt_start_from; ...@@ -284,7 +284,7 @@ our $opt_start_from;
our $opt_strace_client; our $opt_strace_client;
our $opt_timer; our $opt_timer= 1;
our $opt_user; our $opt_user;
our $opt_user_test; our $opt_user_test;
...@@ -682,7 +682,7 @@ sub command_line_setup () { ...@@ -682,7 +682,7 @@ sub command_line_setup () {
'socket=s' => \$opt_socket, 'socket=s' => \$opt_socket,
'start-dirty' => \$opt_start_dirty, 'start-dirty' => \$opt_start_dirty,
'start-and-exit' => \$opt_start_and_exit, 'start-and-exit' => \$opt_start_and_exit,
'timer' => \$opt_timer, 'timer!' => \$opt_timer,
'unified-diff|udiff' => \$opt_udiff, 'unified-diff|udiff' => \$opt_udiff,
'user-test=s' => \$opt_user_test, 'user-test=s' => \$opt_user_test,
'user=s' => \$opt_user, 'user=s' => \$opt_user,
...@@ -3595,15 +3595,17 @@ Options to control what engine/variation to run ...@@ -3595,15 +3595,17 @@ Options to control what engine/variation to run
compress Use the compressed protocol between client and server compress Use the compressed protocol between client and server
ssl Use ssl protocol between client and server ssl Use ssl protocol between client and server
skip-ssl Dont start server with support for ssl connections skip-ssl Dont start server with support for ssl connections
bench Run the benchmark suite FIXME bench Run the benchmark suite
small-bench FIXME small-bench Run the benchmarks with --small-tests --small-tables
Options to control directories to use Options to control directories to use
vardir=DIR The directory where files generated from the test run benchdir=DIR The directory where the benchmark suite is stored
is stored(default: ./var). Specifying a ramdisk or tmpfs (default: ../../mysql-bench)
will speed up tests.
tmpdir=DIR The directory where temporary files are stored tmpdir=DIR The directory where temporary files are stored
(default: ./var/tmp). (default: ./var/tmp).
vardir=DIR The directory where files generated from the test run
is stored (default: ./var). Specifying a ramdisk or
tmpfs will speed up tests.
Options to control what test suites or cases to run Options to control what test suites or cases to run
...@@ -3618,8 +3620,9 @@ Options to control what test suites or cases to run ...@@ -3618,8 +3620,9 @@ Options to control what test suites or cases to run
skip-rpl Skip the replication test cases. skip-rpl Skip the replication test cases.
skip-im Don't start IM, and skip the IM test cases skip-im Don't start IM, and skip the IM test cases
skip-test=PREFIX Skip test cases which name are prefixed with PREFIX skip-test=PREFIX Skip test cases which name are prefixed with PREFIX
big-test Pass "--big-test" to mysqltest which will set the environment big-test Pass "--big-test" to mysqltest which will set the
variable BIG_TEST, which can be checked from test cases. environment variable BIG_TEST, which can be checked
from test cases.
Options that specify ports Options that specify ports
...@@ -3645,25 +3648,29 @@ Options to run test on running server ...@@ -3645,25 +3648,29 @@ Options to run test on running server
Options for debugging the product Options for debugging the product
gdb Start the mysqld(s) in gdb client-ddd Start mysqltest client in ddd
manual-gdb Let user manually start mysqld in gdb, before running test(s) client-debugger=NAME Start mysqltest in the selected debugger
manual-debug Let user manually start mysqld in debugger, before running test(s)
client-gdb Start mysqltest client in gdb client-gdb Start mysqltest client in gdb
ddd Start mysqld in ddd ddd Start mysqld in ddd
client-ddd Start mysqltest client in ddd debug Dump trace output for all servers and client programs
debugger=NAME Start mysqld in the selected debugger debugger=NAME Start mysqld in the selected debugger
client-debugger=NAME Start mysqltest in the selected debugger gdb Start the mysqld(s) in gdb
strace-client FIXME manual-debug Let user manually start mysqld in debugger, before
running test(s)
manual-gdb Let user manually start mysqld in gdb, before running
test(s)
master-binary=PATH Specify the master "mysqld" to use master-binary=PATH Specify the master "mysqld" to use
slave-binary=PATH Specify the slave "mysqld" to use slave-binary=PATH Specify the slave "mysqld" to use
strace-client Create strace output for mysqltest client
Options for coverage, profiling etc Options for coverage, profiling etc
gcov FIXME gcov FIXME
gprof FIXME gprof FIXME
valgrind Run the "mysqltest" and "mysqld" executables using valgrind valgrind Run the "mysqltest" and "mysqld" executables using
valgrind-all Same as "valgrind" but will also add "verbose" and "--show-reachable" valgrind
flags to valgrind valgrind-all Same as "valgrind" but will also add "verbose" and
"--show-reachable" flags to valgrind
valgrind-mysqltest Run the "mysqltest" executable with valgrind valgrind-mysqltest Run the "mysqltest" executable with valgrind
valgrind-mysqld Run the "mysqld" executable with valgrind valgrind-mysqld Run the "mysqld" executable with valgrind
valgrind-options=ARGS Extra options to give valgrind valgrind-options=ARGS Extra options to give valgrind
...@@ -3672,10 +3679,10 @@ Options for coverage, profiling etc ...@@ -3672,10 +3679,10 @@ Options for coverage, profiling etc
Misc options Misc options
comment=STR Write STR to the output comment=STR Write STR to the output
notimer Don't show test case execution time
script-debug Debug this script itself script-debug Debug this script itself
timer Show test case execution time start-and-exit Only initiate and start the "mysqld" servers, use
start-and-exit Only initiate and start the "mysqld" servers, use the startup the startup settings for the specified test case if any
settings for the specified test case if any
start-dirty Only start the "mysqld" servers without initiation start-dirty Only start the "mysqld" servers without initiation
fast Don't try to cleanup from earlier runs fast Don't try to cleanup from earlier runs
reorder Reorder tests to get less server restarts reorder Reorder tests to get less server restarts
...@@ -3690,7 +3697,6 @@ Deprecated options ...@@ -3690,7 +3697,6 @@ Deprecated options
Options not yet described, or that I want to look into more Options not yet described, or that I want to look into more
debug
local local
local-master local-master
netware netware
......
...@@ -6,13 +6,6 @@ attr1 INT NOT NULL, ...@@ -6,13 +6,6 @@ attr1 INT NOT NULL,
attr2 INT, attr2 INT,
attr3 VARCHAR(10) attr3 VARCHAR(10)
) ENGINE=ndbcluster; ) ENGINE=ndbcluster;
drop table t1;
CREATE TABLE t1 (
pk1 INT NOT NULL PRIMARY KEY,
attr1 INT NOT NULL,
attr2 INT,
attr3 VARCHAR(10)
) ENGINE=ndbcluster;
SHOW INDEX FROM t1; SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 pk1 A 0 NULL NULL BTREE t1 0 PRIMARY 1 pk1 A 0 NULL NULL BTREE
......
...@@ -201,21 +201,21 @@ create table t1 ( ...@@ -201,21 +201,21 @@ create table t1 (
pk1 bit(9) not null primary key, pk1 bit(9) not null primary key,
b int b int
) engine=ndbcluster; ) engine=ndbcluster;
ERROR HY000: Can't create table 'test.t1' (errno: 140) ERROR HY000: Can't create table 'test.t1' (errno: 906)
show warnings; show warnings;
Level Code Message Level Code Message
Error 1296 Got error 739 'Unsupported primary key length' from NDB Error 1296 Got error 906 'Unsupported attribute type in index' from NDB
Error 1005 Can't create table 'test.t1' (errno: 140) Error 1005 Can't create table 'test.t1' (errno: 906)
create table t1 ( create table t1 (
pk1 int not null primary key, pk1 int not null primary key,
b bit(9), b bit(9),
key(b) key(b)
) engine=ndbcluster; ) engine=ndbcluster;
ERROR HY000: Can't create table 'test.t1' (errno: 140) ERROR HY000: Can't create table 'test.t1' (errno: 906)
show warnings; show warnings;
Level Code Message Level Code Message
Error 1296 Got error 743 'Unsupported character set in table or index' from NDB Error 1296 Got error 906 'Unsupported attribute type in index' from NDB
Error 1005 Can't create table 'test.t1' (errno: 140) Error 1005 Can't create table 'test.t1' (errno: 906)
create table t1 ( create table t1 (
pk1 int primary key, pk1 int primary key,
b bit(32) not null b bit(32) not null
......
stop slave;
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;
start slave;
SHOW VARIABLES LIKE 'relay_log_space_limit';
Variable_name Value
relay_log_space_limit 0
CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=NDB;
INSERT INTO t1 SET name='Andy', age=31;
INSERT INTO t1 SET name='Jacob', age=2;
INSERT INTO t1 SET name='Caleb', age=1;
ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1 ORDER BY id;
name age id
Andy 31 00000001
Caleb 1 00000002
Jacob 2 00000003
SELECT * FROM t1 ORDER BY id;
name age id
Andy 31 00000001
Caleb 1 00000002
Jacob 2 00000003
DROP TABLE t1;
...@@ -48,6 +48,7 @@ udf : BUG#18564 2006-03-27 ian (Permission by Brian) ...@@ -48,6 +48,7 @@ udf : BUG#18564 2006-03-27 ian (Permission by Brian)
#ndb_load : BUG#17233 2006-02-16 jmiller failed load data from infile causes mysqld dbug_assert, binlog not flushed #ndb_load : BUG#17233 2006-02-16 jmiller failed load data from infile causes mysqld dbug_assert, binlog not flushed
#rpl_ndb_basic : BUG#18592 2006-03-28 brian rpl_ndb_basic failure #rpl_ndb_basic : BUG#18592 2006-03-28 brian rpl_ndb_basic failure
#rpl_ndb_dd_advance : BUG#18924 2006-04-09 brian rpl_ndb_dd_advance failure #rpl_ndb_dd_advance : BUG#18924 2006-04-09 brian rpl_ndb_dd_advance failure
rpl_ndb_dd_partitions : BUG#18094 2006-04-19 mats Slave caches invalid table definition...
#rpl_ndb_dd_basic : BUG#18569 2006-03-28 brian rpl_ndb_dd_basic failure #rpl_ndb_dd_basic : BUG#18569 2006-03-28 brian rpl_ndb_dd_basic failure
#rpl_ndb_insert_ignore : BUG#18567 2006-03-28 brian rpl_ndb_insert_ignore failure #rpl_ndb_insert_ignore : BUG#18567 2006-03-28 brian rpl_ndb_insert_ignore failure
#rpl_ndb_multi_update2 : BUG#18928 2006-04-09 brian rpl_ndb_multi_update2 failed #rpl_ndb_multi_update2 : BUG#18928 2006-04-09 brian rpl_ndb_multi_update2 failed
......
...@@ -6,17 +6,6 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7; ...@@ -6,17 +6,6 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
drop database if exists mysqltest; drop database if exists mysqltest;
--enable_warnings --enable_warnings
# workaround for bug#16445
# remove to reproduce bug and run tests drom ndb start
# and with ndb_autodiscover disabled
CREATE TABLE t1 (
pk1 INT NOT NULL PRIMARY KEY,
attr1 INT NOT NULL,
attr2 INT,
attr3 VARCHAR(10)
) ENGINE=ndbcluster;
drop table t1;
# #
# Basic test to show that the NDB # Basic test to show that the NDB
# table handler is working # table handler is working
......
###################################
# Wrapper rpl_sv_relay_space.test #
# This test has to be wrapped as #
# It tests ndb, innodb and MyISAM.#
# By Wrapping we are saving some #
# space and making the test more #
# Maintainable by only having one #
# test file and reusing the code #
# In Addition, INNODB has to have #
# Option files during this test #
# to force innodb on the slave #
# else the test will fail #
###################################
#Change Author: JBM #
#Change Date: 2006-02-03 #
#Change: Added Comments #
###################################
--source include/have_ndb.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_sv_relay_space.test
use mysql;
--
-- merging `host` table and `db`
--
UPDATE IGNORE host SET Host='%' WHERE Host='';
DELETE FROM host WHERE Host='';
INSERT IGNORE INTO db (User, Host, Select_priv, Insert_priv, Update_priv,
Delete_priv, Create_priv, Drop_priv, Grant_priv, References_priv,
Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv)
SELECT d.User, h.Host,
(d.Select_priv = 'Y' || h.Select_priv = 'Y') + 1,
(d.Insert_priv = 'Y' || h.Select_priv = 'Y') + 1,
(d.Update_priv = 'Y' || h.Update_priv = 'Y') + 1,
(d.Delete_priv = 'Y' || h.Delete_priv = 'Y') + 1,
(d.Create_priv = 'Y' || h.Create_priv = 'Y') + 1,
(d.Drop_priv = 'Y' || h.Drop_priv = 'Y') + 1,
(d.Grant_priv = 'Y' || h.Grant_priv = 'Y') + 1,
(d.References_priv = 'Y' || h.References_priv = 'Y') + 1,
(d.Index_priv = 'Y' || h.Index_priv = 'Y') + 1,
(d.Alter_priv = 'Y' || h.Alter_priv = 'Y') + 1,
(d.Create_tmp_table_priv = 'Y' || h.Create_tmp_table_priv = 'Y') + 1,
(d.Lock_tables_priv = 'Y' || h.Lock_tables_priv = 'Y') + 1
FROM db d, host h WHERE d.Host = '';
UPDATE IGNORE db SET Host='%' WHERE Host = '';
DELETE FROM db WHERE Host='';
TRUNCATE TABLE host;
--
-- Adding missing users to `user` table
--
-- note that invalid password causes the user to be skipped during the
-- load of grand tables (at mysqld startup) thus three following inserts
-- do not affect anything
INSERT IGNORE user (User, Host, Password) SELECT User, Host, "*" FROM db;
INSERT IGNORE user (User, Host, Password) SELECT User, Host, "*" FROM tables_priv;
INSERT IGNORE user (User, Host, Password) SELECT User, Host, "*" FROM columns_priv;
SELECT DISTINCT
"There are user accounts with the username 'PUBLIC'. In the SQL-1999
(or later) standard this name is reserved for PUBLIC role and can
not be used as a valid user name. Consider renaming these accounts before
upgrading to MySQL-5.0.
These accounts are:" x
FROM user WHERE user='PUBLIC';
SELECT CONCAT(user,'@',host) FROM user WHERE user='PUBLIC';
#!/bin/sh
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
#
# scripts to start the MySQL demon and restart it if it dies unexpectedly
#
# This should be executed in the MySQL base directory if you are using a
# binary installation that has other paths than you are using.
#
# mysql.server works by first doing a cd to the base directory and from there
# executing mysqld_safe
# Check if we are starting this relative (for the binary release)
if test -f ./data/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
-x ./bin/mysqld
then
MY_BASEDIR_VERSION=`pwd` # Where bin, share and data is
DATADIR=$MY_BASEDIR_VERSION/data # Where the databases are
ledir=$MY_BASEDIR_VERSION/bin # Where mysqld are
# Check if this is a 'moved install directory'
elif test -f ./var/mysql/db.frm -a -f ./share/mysql/english/errmsg.sys -a \
-x ./libexec/mysqld
then
MY_BASEDIR_VERSION=`pwd` # Where libexec, share and var is
DATADIR=$MY_BASEDIR_VERSION/var # Where the databases are
ledir=$MY_BASEDIR_VERSION/libexec # Where mysqld are
else
MY_BASEDIR_VERSION=/usr/local/mysql
DATADIR=/usr/local/mysql/var
ledir=/usr/local/mysql/libexec
fi
hostname=`@HOSTNAME@`
pidfile=$DATADIR/$hostname.pid
log=$DATADIR/$hostname.log
err=$DATADIR/$hostname.err
lockfile=$DATADIR/$hostname.lock
#
# If there exists an old pid file, check if the demon is already running
# Note: The switches to 'ps' may depend on your operating system
if test -f $pidfile
then
PID=`cat $pidfile`
if /bin/kill -0 $PID
then
if /bin/ps -p $PID | grep mysqld > /dev/null
then # The pid contains a mysqld process
echo "A mysqld process already exists"
echo "A mysqld process already exists at " `date` >> $log
exit 1;
fi
fi
rm -f $pidfile
if test -f $pidfile
then
echo "Fatal error: Can't remove the pid file: $pidfile"
echo "Fatal error: Can't remove the pid file: $pidfile at " `date` >> $log
echo "Please remove it manually and start $0 again"
echo "mysqld demon not started"
exit 1;
fi
fi
echo "Starting mysqld demon with databases from $DATADIR"
#Default communication ports
#MYSQL_TCP_PORT=3306
if test -z "$MYSQL_UNIX_PORT"
then
MYSQL_UNIX_PORT="/tmp/mysql.sock"
export MYSQL_UNIX_PORT
fi
#export MYSQL_TCP_PORT
# Does this work on all systems?
#if type ulimit | grep "shell builtin" > /dev/null
#then
# ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems
#fi
echo "mysqld started on " `date` >> $log
bin/zap -f $lockfile < /dev/null > /dev/null 2>&1
rm -f $lockfile
$MY_BASEDIR_VERSION/bin/watchdog_mysqld $lockfile $pidfile $MY_BASEDIR_VERSION/bin $DATADIR 3 10 >> $err 2>&1 &
restart_pid=$!
while true
do
rm -f $MYSQL_UNIX_PORT $pidfile # Some extra safety
lockfile -1 -r10 $lockfile >/dev/null 2>&1
if test "$#" -eq 0
then
nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
--skip-locking >> $err 2>&1 &
else
nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \
--skip-locking "$@" >> $err 2>&1 &
fi
pid=$!
rm -f $lockfile
wait $pid;
lockfile -1 -r10 $lockfile >/dev/null 2>&1
rm -f $lockfile
if test ! -f $pidfile # This is removed if normal shutdown
then
break;
fi
if true
then
# Test if one proces was hanging.
# This is only a fix for Linux (running as base 3 mysqld processes)
# but should work for the rest of the servers.
# The only thing is ps x => redhat 5 gives warnings when using ps -x.
# kill -9 is used or the proces won't react on the kill.
numofproces=`ps x | grep -v "grep" | grep -c $ledir/mysqld`
echo -e "\nNumber of processes running now: $numofproces" | tee -a $log
I=1
while test "$I" -le "$numofproces"
do
PROC=`ps x | grep $ledir/mysqld | grep -v "grep" | tail -1`
for T in $PROC
do
break
done
# echo "TEST $I - $T **"
if kill -9 $T
then
echo "mysqld proces hanging, pid $T - killed" | tee -a $log
else
break
fi
I=`expr $I + 1`
done
fi
echo "mysqld restarted" | tee -a $log
# Check all tables and repair any wrong tables.
$MY_BASEDIR_VERSION/bin/isamchk -sf $DATADIR/*/*.ISM >> $err 2>&1
done
if test $restart_pid -gt 0
then
kill $restart_pid > /dev/null 2>&1
sleep 1;
kill -9 $restart_pid > /dev/null 2>&1
fi
echo -n "mysqld ended on " `date` >> $log
echo "mysqld demon ended"
...@@ -5989,7 +5989,7 @@ int Field_str::store(double nr) ...@@ -5989,7 +5989,7 @@ int Field_str::store(double nr)
uint Field::is_equal(create_field *new_field) uint Field::is_equal(create_field *new_field)
{ {
return (new_field->sql_type == type()); return (new_field->sql_type == real_type());
} }
...@@ -6001,7 +6001,7 @@ uint Field_str::is_equal(create_field *new_field) ...@@ -6001,7 +6001,7 @@ uint Field_str::is_equal(create_field *new_field)
(flags & (BINCMP_FLAG | BINARY_FLAG)))) (flags & (BINCMP_FLAG | BINARY_FLAG))))
return 0; /* One of the fields is binary and the other one isn't */ return 0; /* One of the fields is binary and the other one isn't */
return ((new_field->sql_type == type()) && return ((new_field->sql_type == real_type()) &&
new_field->charset == field_charset && new_field->charset == field_charset &&
new_field->length == max_length()); new_field->length == max_length());
} }
...@@ -6798,7 +6798,7 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, ...@@ -6798,7 +6798,7 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root,
uint Field_varstring::is_equal(create_field *new_field) uint Field_varstring::is_equal(create_field *new_field)
{ {
if (new_field->sql_type == type() && if (new_field->sql_type == real_type() &&
new_field->charset == field_charset) new_field->charset == field_charset)
{ {
if (new_field->length == max_length()) if (new_field->length == max_length())
...@@ -7957,12 +7957,12 @@ bool Field_num::eq_def(Field *field) ...@@ -7957,12 +7957,12 @@ bool Field_num::eq_def(Field *field)
uint Field_num::is_equal(create_field *new_field) uint Field_num::is_equal(create_field *new_field)
{ {
return ((new_field->sql_type == type()) && return ((new_field->sql_type == real_type()) &&
((new_field->flags & UNSIGNED_FLAG) == (uint) (flags & ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags &
UNSIGNED_FLAG)) && UNSIGNED_FLAG)) &&
((new_field->flags & AUTO_INCREMENT_FLAG) == ((new_field->flags & AUTO_INCREMENT_FLAG) ==
(uint) (flags & AUTO_INCREMENT_FLAG)) && (uint) (flags & AUTO_INCREMENT_FLAG)) &&
(new_field->length >= max_length())); (new_field->length <= max_length()));
} }
......
...@@ -1430,6 +1430,10 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, ...@@ -1430,6 +1430,10 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
NDB_SHARE *share) NDB_SHARE *share)
{ {
DBUG_ENTER("ndb_handle_schema_change"); DBUG_ENTER("ndb_handle_schema_change");
TABLE* table= share->table;
TABLE_SHARE *table_share= table->s;
const char *dbname= table_share->db.str;
const char *tabname= table_share->table_name.str;
bool do_close_cached_tables= FALSE; bool do_close_cached_tables= FALSE;
bool is_online_alter_table= FALSE; bool is_online_alter_table= FALSE;
bool is_rename_table= FALSE; bool is_rename_table= FALSE;
...@@ -1449,70 +1453,68 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, ...@@ -1449,70 +1453,68 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
} }
} }
if (is_remote_change) /* includes CLUSTER_FAILURE */ /*
Refresh local dictionary cache by
invalidating table and all it's indexes
*/
ndb->setDatabaseName(dbname);
Thd_ndb *thd_ndb= get_thd_ndb(thd);
DBUG_ASSERT(thd_ndb != NULL);
Ndb* old_ndb= thd_ndb->ndb;
thd_ndb->ndb= ndb;
ha_ndbcluster table_handler(table_share);
(void)strxmov(table_handler.m_dbname, dbname, NullS);
(void)strxmov(table_handler.m_tabname, tabname, NullS);
table_handler.open_indexes(ndb, table, TRUE);
table_handler.invalidate_dictionary_cache(TRUE);
thd_ndb->ndb= old_ndb;
/*
Refresh local frm file and dictionary cache if
remote on-line alter table
*/
if (is_remote_change && is_online_alter_table)
{ {
TABLE* table= share->table; const char *tabname= table_share->table_name.str;
TABLE_SHARE *table_share= table->s; char key[FN_REFLEN];
const char *dbname= table_share->db.str; const void *data= 0, *pack_data= 0;
uint length, pack_length;
int error;
NDBDICT *dict= ndb->getDictionary();
const NDBTAB *altered_table= pOp->getTable();
/* DBUG_PRINT("info", ("Detected frm change of table %s.%s",
Invalidate table and all it's indexes dbname, tabname));
build_table_filename(key, FN_LEN-1, dbname, tabname, NullS);
/*
If the frm of the altered table is different than the one on
disk then overwrite it with the new table definition
*/ */
ndb->setDatabaseName(dbname); if (readfrm(key, &data, &length) == 0 &&
Thd_ndb *thd_ndb= get_thd_ndb(thd); packfrm(data, length, &pack_data, &pack_length) == 0 &&
DBUG_ASSERT(thd_ndb != NULL); cmp_frm(altered_table, pack_data, pack_length))
Ndb* old_ndb= thd_ndb->ndb; {
thd_ndb->ndb= ndb; DBUG_DUMP("frm", (char*)altered_table->getFrmData(),
ha_ndbcluster table_handler(table_share); altered_table->getFrmLength());
table_handler.set_dbname(share->key); pthread_mutex_lock(&LOCK_open);
table_handler.set_tabname(share->key); const NDBTAB *old= dict->getTable(tabname);
table_handler.open_indexes(ndb, table, TRUE); if (!old &&
table_handler.invalidate_dictionary_cache(TRUE); old->getObjectVersion() != altered_table->getObjectVersion())
thd_ndb->ndb= old_ndb; dict->putTable(altered_table);
if (is_online_alter_table) if ((error= unpackfrm(&data, &length, altered_table->getFrmData())) ||
{ (error= writefrm(key, data, length)))
const char *tabname= table_share->table_name.str;
char key[FN_REFLEN];
const void *data= 0, *pack_data= 0;
uint length, pack_length;
int error;
NDBDICT *dict= ndb->getDictionary();
const NDBTAB *altered_table= pOp->getTable();
DBUG_PRINT("info", ("Detected frm change of table %s.%s",
dbname, tabname));
build_table_filename(key, FN_LEN-1, dbname, tabname, NullS);
/*
If the frm of the altered table is different than the one on
disk then overwrite it with the new table definition
*/
if (readfrm(key, &data, &length) == 0 &&
packfrm(data, length, &pack_data, &pack_length) == 0 &&
cmp_frm(altered_table, pack_data, pack_length))
{ {
DBUG_DUMP("frm", (char*)altered_table->getFrmData(), sql_print_information("NDB: Failed write frm for %s.%s, error %d",
altered_table->getFrmLength()); dbname, tabname, error);
pthread_mutex_lock(&LOCK_open);
const NDBTAB *old= dict->getTable(tabname);
if (!old &&
old->getObjectVersion() != altered_table->getObjectVersion())
dict->putTable(altered_table);
if ((error= unpackfrm(&data, &length, altered_table->getFrmData())) ||
(error= writefrm(key, data, length)))
{
sql_print_information("NDB: Failed write frm for %s.%s, error %d",
dbname, tabname, error);
}
ndbcluster_binlog_close_table(thd, share);
close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, TRUE);
if ((error= ndbcluster_binlog_open_table(thd, share,
table_share, table)))
sql_print_information("NDB: Failed to re-open table %s.%s",
dbname, tabname);
pthread_mutex_unlock(&LOCK_open);
} }
ndbcluster_binlog_close_table(thd, share);
close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0, TRUE);
if ((error= ndbcluster_binlog_open_table(thd, share,
table_share, table)))
sql_print_information("NDB: Failed to re-open table %s.%s",
dbname, tabname);
pthread_mutex_unlock(&LOCK_open);
} }
} }
...@@ -1540,6 +1542,21 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, ...@@ -1540,6 +1542,21 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
share->table->s->db.length= strlen(share->db); share->table->s->db.length= strlen(share->db);
share->table->s->table_name.str= share->table_name; share->table->s->table_name.str= share->table_name;
share->table->s->table_name.length= strlen(share->table_name); share->table->s->table_name.length= strlen(share->table_name);
/*
Refresh local dictionary cache by invalidating any
old table with same name and all it's indexes
*/
ndb->setDatabaseName(dbname);
Thd_ndb *thd_ndb= get_thd_ndb(thd);
DBUG_ASSERT(thd_ndb != NULL);
Ndb* old_ndb= thd_ndb->ndb;
thd_ndb->ndb= ndb;
ha_ndbcluster table_handler(table_share);
table_handler.set_dbname(share->key);
table_handler.set_tabname(share->key);
table_handler.open_indexes(ndb, table, TRUE);
table_handler.invalidate_dictionary_cache(TRUE);
thd_ndb->ndb= old_ndb;
} }
DBUG_ASSERT(share->op == pOp || share->op_old == pOp); DBUG_ASSERT(share->op == pOp || share->op_old == pOp);
if (share->op_old == pOp) if (share->op_old == pOp)
......
#!/usr/bin/perl
# Copyright (C) 1979-1998 TcX AB & Monty Program KB & Detron HB
#
# This software is distributed with NO WARRANTY OF ANY KIND. No author or
# distributor accepts any responsibility for the consequences of using it, or
# for whether it serves any particular purpose or works at all, unless he or
# she says so in writing. Refer to the Free Public License (the "License")
# for full details.
#
# Every copy of this file must include a copy of the License, normally in a
# plain ASCII text file named PUBLIC. The License grants you the right to
# copy, modify and redistribute this file, but only under certain conditions
# described in the License. Among other things, the License requires that
# the copyright notice and this notice be preserved on all copies. */
#
# This scripts is started by safe_mysqld. It checks that MySQL is alive and
# working ( = answering to ping). If not, force mysqld down, check all
# tables and let safe_mysqld restart the server.
#
# For this to work, you should have procmail installed as the commands
# 'lockfile' and is used to sync with safe_mysqld
#
# NOTE: You should only use this script as a last resort if mysqld locks
# up unexpectedly in a critical application and you have to get it to
# work temporarily while waiting for a solution from mysql@tcx.se or
# mysql-support@tcx.se
use POSIX "waitpid";
# Arguments from safe_mysqld
if ($#ARGV != 4)
{
print "$0: Wrong number of arguments. Aborting\n";
exit 1;
}
$lock_file=shift; # File to lock to sync with safe_mysqld
$pid_file=shift; # Pid file used by mysqld
$bin_dir=shift; # Directory where mysqladmin is
$test_timeout=shift; # Time between testing if mysqld is alive
$wait_timeout=shift; # How long time to wait for ping
$|=1; # autoflush
# Check that mysqld has started properly
for ($i=1 ; $i < 10 ; $i ++)
{
last if (-e $pid_file);
}
sleep(1); # If server has just created the file
if (($mysqld_pid=`cat $pid_file`) <= 0)
{
print "$0: Error: Invalid pidfile (contains '$mysqld_pid'). Aborting\n";
}
# Start pinging mysqld
for (;;)
{
sleep($test_timeout); # Time between tests
`lockfile $lock_file > /dev/null 2>&1`; # Sync with safe_mysqld
if (($pid=fork()) == 0)
{
setpgrp(0,0);
exit(int(system("$bin_dir/mysqladmin -w status > /dev/null")/256));
}
for ($i=0; ($res=waitpid(-1,&POSIX::WNOHANG)) == 0 && $i < $wait_timeout ; $i++)
{
sleep(1);
}
if ($res == 0)
{
print "$0: Warning: mysqld hanged; Killing it so that safe_mysqld can restart it!\n";
$mysqld_pid= `cat $pid_file`;
if ($mysqld_pid <= 0)
{
print "$0: Error: Invalid pidfile (contains '$mysqld_pid'). Aborting\n";
system("rm -f $lock_file");
kill(-9,$pid);
exit 1;
}
print "$0: Sending signal 15 to $mysqld_pid\n";
kill(-15, $pid,$mysqld_pid); # Give it a last change to die nicely
for ($i=0 ; $i < 5 ; $i++) { sleep(1); } # Wait 5 seconds (signal safe)
waitpid(-1,&POSIX::WNOHANG);
if (kill(0,$pid,$mysqld_pid) != 0)
{
print "$0: Sending signal 9 to $mysqld_pid\n";
kill(-9,$pid,$mysqld_pid); # No time to be nice anymore
sleep(2); # Give system time to clean up
waitpid(-1,&POSIX::WNOHANG);
if (kill(0,$mysqld_pid) != 0)
{
print "$0: Warning: mysqld don't want to die. Aborting\n";
system("rm -f $lock_file");
exit 1;
}
}
# safe_mysqld will not restart mysqld if the pid file doesn't exists
system("rm $pid_file");
system("touch $pid_file");
}
elsif ($res == -1)
{
print "$0: Error: waitpid returned $res when wating for pid $pid\nPlease verify that $0 is correct for your system\n";
system("rm -f $lock_file");
exit 1;
}
else
{
$exit_code=int($?/256);
if ($exit_code != 0)
{
print "$0: Warning: mysqladmin returned exit code $exit_code\n";
}
else
{
#print "mysqld is alive and feeling well\n";
}
}
system("rm -f $lock_file"); # safemysqld will now take over
}
...@@ -147,7 +147,8 @@ public: ...@@ -147,7 +147,8 @@ public:
enum ErrorCode { enum ErrorCode {
NoError = 0, NoError = 0,
InvalidCharset = 743, InvalidCharset = 743,
TooManyBitsUsed = 831 TooManyBitsUsed = 831,
UnsupportedType = 906
}; };
private: private:
Uint32 userPtr; Uint32 userPtr;
......
...@@ -117,9 +117,9 @@ public: ...@@ -117,9 +117,9 @@ public:
/** /**
* Check character set. * Check character set.
*/ */
static bool usable_in_pk(Uint32 typeId, const void* info); static uint check_column_for_pk(Uint32 typeId, const void* info);
static bool usable_in_hash_index(Uint32 typeId, const void* info); static uint check_column_for_hash_index(Uint32 typeId, const void* info);
static bool usable_in_ordered_index(Uint32 typeId, const void* info); static uint check_column_for_ordered_index(Uint32 typeId, const void* info);
/** /**
* Get number of length bytes and length from variable length string. * Get number of length bytes and length from variable length string.
......
...@@ -872,8 +872,8 @@ NdbSqlUtil::likeLongvarbinary(const void* info, const void* p1, unsigned n1, con ...@@ -872,8 +872,8 @@ NdbSqlUtil::likeLongvarbinary(const void* info, const void* p1, unsigned n1, con
// check charset // check charset
bool uint
NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) NdbSqlUtil::check_column_for_pk(Uint32 typeId, const void* info)
{ {
const Type& type = getType(typeId); const Type& type = getType(typeId);
switch (type.m_typeId) { switch (type.m_typeId) {
...@@ -882,12 +882,14 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) ...@@ -882,12 +882,14 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
case Type::Longvarchar: case Type::Longvarchar:
{ {
const CHARSET_INFO *cs = (const CHARSET_INFO*)info; const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
return if(cs != 0 &&
cs != 0 && cs->cset != 0 &&
cs->cset != 0 && cs->coll != 0 &&
cs->coll != 0 && cs->coll->strnxfrm != 0 &&
cs->coll->strnxfrm != 0 && cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY; return 0;
else
return 743;
} }
break; break;
case Type::Undefined: case Type::Undefined:
...@@ -896,19 +898,19 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) ...@@ -896,19 +898,19 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info)
case Type::Bit: case Type::Bit:
break; break;
default: default:
return true; return 0;
} }
return false; return 906;
} }
bool uint
NdbSqlUtil::usable_in_hash_index(Uint32 typeId, const void* info) NdbSqlUtil::check_column_for_hash_index(Uint32 typeId, const void* info)
{ {
return usable_in_pk(typeId, info); return check_column_for_pk(typeId, info);
} }
bool uint
NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) NdbSqlUtil::check_column_for_ordered_index(Uint32 typeId, const void* info)
{ {
const Type& type = getType(typeId); const Type& type = getType(typeId);
if (type.m_cmp == NULL) if (type.m_cmp == NULL)
...@@ -919,13 +921,15 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) ...@@ -919,13 +921,15 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
case Type::Longvarchar: case Type::Longvarchar:
{ {
const CHARSET_INFO *cs = (const CHARSET_INFO*)info; const CHARSET_INFO *cs = (const CHARSET_INFO*)info;
return if (cs != 0 &&
cs != 0 && cs->cset != 0 &&
cs->cset != 0 && cs->coll != 0 &&
cs->coll != 0 && cs->coll->strnxfrm != 0 &&
cs->coll->strnxfrm != 0 && cs->coll->strnncollsp != 0 &&
cs->coll->strnncollsp != 0 && cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY)
cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY; return 0;
else
return 743;
} }
break; break;
case Type::Undefined: case Type::Undefined:
...@@ -934,9 +938,9 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) ...@@ -934,9 +938,9 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info)
case Type::Bit: // can be fixed case Type::Bit: // can be fixed
break; break;
default: default:
return true; return 0;
} }
return false; return 906;
} }
// utilities // utilities
......
...@@ -215,11 +215,12 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) ...@@ -215,11 +215,12 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal)
break; break;
} }
if (descAttr.m_charset != 0) { if (descAttr.m_charset != 0) {
uint err;
CHARSET_INFO *cs = all_charsets[descAttr.m_charset]; CHARSET_INFO *cs = all_charsets[descAttr.m_charset];
ndbrequire(cs != 0); ndbrequire(cs != 0);
if (! NdbSqlUtil::usable_in_ordered_index(descAttr.m_typeId, cs)) { if ((err = NdbSqlUtil::check_column_for_ordered_index(descAttr.m_typeId, cs))) {
jam(); jam();
errorCode = TuxAddAttrRef::InvalidCharset; errorCode = (TuxAddAttrRef::ErrorCode) err;
break; break;
} }
} }
......
...@@ -2292,7 +2292,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, ...@@ -2292,7 +2292,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
NdbTableImpl & impl, NdbTableImpl & impl,
bool alter) bool alter)
{ {
unsigned i; unsigned i, err;
char *ts_names[MAX_NDB_PARTITIONS]; char *ts_names[MAX_NDB_PARTITIONS];
DBUG_ENTER("NdbDictInterface::createOrAlterTable"); DBUG_ENTER("NdbDictInterface::createOrAlterTable");
...@@ -2593,8 +2593,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, ...@@ -2593,8 +2593,10 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
// primary key type check // primary key type check
if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) { if (col->m_pk &&
m_error.code= (col->m_cs != 0 ? 743 : 739); (err = NdbSqlUtil::check_column_for_pk(col->m_type, col->m_cs)))
{
m_error.code= err;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
// distribution key not supported for Char attribute // distribution key not supported for Char attribute
...@@ -3025,7 +3027,7 @@ NdbDictInterface::createIndex(Ndb & ndb, ...@@ -3025,7 +3027,7 @@ NdbDictInterface::createIndex(Ndb & ndb,
{ {
//validate(); //validate();
//aggregate(); //aggregate();
unsigned i; unsigned i, err;
UtilBufferWriter w(m_buffer); UtilBufferWriter w(m_buffer);
const size_t len = strlen(impl.m_externalName.c_str()) + 1; const size_t len = strlen(impl.m_externalName.c_str()) + 1;
if(len > MAX_TAB_NAME_SIZE) { if(len > MAX_TAB_NAME_SIZE) {
...@@ -3074,10 +3076,12 @@ NdbDictInterface::createIndex(Ndb & ndb, ...@@ -3074,10 +3076,12 @@ NdbDictInterface::createIndex(Ndb & ndb,
// index key type check // index key type check
if (it == DictTabInfo::UniqueHashIndex && if (it == DictTabInfo::UniqueHashIndex &&
! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) || (err = NdbSqlUtil::check_column_for_hash_index(col->m_type, col->m_cs))
||
it == DictTabInfo::OrderedIndex && it == DictTabInfo::OrderedIndex &&
! NdbSqlUtil::usable_in_ordered_index(col->m_type, col->m_cs)) { (err = NdbSqlUtil::check_column_for_ordered_index(col->m_type, col->m_cs)))
m_error.code = 743; {
m_error.code = err;
return -1; return -1;
} }
// API uses external column number to talk to DICT // API uses external column number to talk to DICT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment