Commit 14f8afc9 authored by unknown's avatar unknown

Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1

into ice.snake.net:/Volumes/ice2/MySQL/bk/mysql-4.1

parents 7d3b20e3 ae99cc1f
...@@ -154,6 +154,7 @@ ram@gw.udmsearch.izhnet.ru ...@@ -154,6 +154,7 @@ ram@gw.udmsearch.izhnet.ru
ram@mysql.r18.ru ram@mysql.r18.ru
ram@ram.(none) ram@ram.(none)
ranger@regul.home.lan ranger@regul.home.lan
rburnett@build.mysql.com
root@home.(none) root@home.(none)
root@x3.internalnet root@x3.internalnet
salle@banica.(none) salle@banica.(none)
......
...@@ -115,6 +115,9 @@ sub main ...@@ -115,6 +115,9 @@ sub main
# fix file copyrights # fix file copyrights
&fix_usage_copyright(); &fix_usage_copyright();
&add_copyright(); &add_copyright();
# fix LICENSE tag in include/mysql_version.h
&fix_mysql_version();
# rename the directory with new distribution name # rename the directory with new distribution name
chdir("$WD/$dir"); chdir("$WD/$dir");
...@@ -141,6 +144,28 @@ sub main ...@@ -141,6 +144,28 @@ sub main
exit(0); exit(0);
} }
####
#### This function will s/GPL/Commercial/ in include/mysql_version.h for the
#### LICENSE tag.
####
sub fix_mysql_version
{
chdir("$destdir");
my $header_file= (-f 'include/mysql_version.h.in')? 'include/mysql_version.h.in' : 'include/mysql_version.h';
open(MYSQL_VERSION,"<$header_file") or die "Unable to open include/mysql_version.h for read: $!\n";
undef $/;
my $mysql_version= <MYSQL_VERSION>;
close(MYSQL_VERSION);
$mysql_version=~ s/\#define LICENSE[\s\t]+GPL/#define LICENSE Commercial/;
open(MYSQL_VERSION,">$header_file") or die "Unable to open include/mysql_version.h for write: $!\n";
print MYSQL_VERSION $mysql_version;
close(MYSQL_VERSION);
chdir("$cwd");
}
#### ####
#### This function will remove unwanted parts of a src tree for the mysqlcom #### This function will remove unwanted parts of a src tree for the mysqlcom
#### distributions. #### distributions.
...@@ -151,11 +176,7 @@ sub trim_the_fat ...@@ -151,11 +176,7 @@ sub trim_the_fat
my $cwd= getcwd(); my $cwd= getcwd();
system("rm -rf $destdir/${the_fat}"); system("rm -rf $destdir/${the_fat}");
if ($win_flag) if (!$win_flag)
{
chdir("$destdir") or die "Unable to change directory to $destdir!: $!\n";
}
else
{ {
chdir("$destdir"); chdir("$destdir");
unlink ("configure") or die "Can't delete $destdir/configure: $!\n"; unlink ("configure") or die "Can't delete $destdir/configure: $!\n";
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
C_MODE_START C_MODE_START
extern ulonglong log_10_int[20]; extern ulonglong log_10_int[20];
extern uchar days_in_month[];
/* /*
Portable time_t replacement. Portable time_t replacement.
......
...@@ -21,8 +21,7 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include ...@@ -21,8 +21,7 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \ LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \ $(top_builddir)/dbug/libdbug.a \
@ZLIB_LIBS@ \ $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
$(top_builddir)/strings/libmystrings.a
pkglib_LIBRARIES = libmyisam.a pkglib_LIBRARIES = libmyisam.a
bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
myisamchk_DEPENDENCIES= $(LIBRARIES) myisamchk_DEPENDENCIES= $(LIBRARIES)
......
...@@ -5,6 +5,7 @@ DataMemory: CHOOSE_DataMemory ...@@ -5,6 +5,7 @@ DataMemory: CHOOSE_DataMemory
IndexMemory: CHOOSE_IndexMemory IndexMemory: CHOOSE_IndexMemory
Diskless: CHOOSE_Diskless Diskless: CHOOSE_Diskless
TimeBetweenWatchDogCheck: 30000 TimeBetweenWatchDogCheck: 30000
FileSystemPath: CHOOSE_FILESYSTEM
[COMPUTER] [COMPUTER]
Id: 1 Id: 1
...@@ -16,11 +17,9 @@ HostName: CHOOSE_HOSTNAME_2 ...@@ -16,11 +17,9 @@ HostName: CHOOSE_HOSTNAME_2
[DB] [DB]
ExecuteOnComputer: 1 ExecuteOnComputer: 1
FileSystemPath: CHOOSE_FILESYSTEM_NODE_1
[DB] [DB]
ExecuteOnComputer: 2 ExecuteOnComputer: 2
FileSystemPath: CHOOSE_FILESYSTEM_NODE_2
[MGM] [MGM]
PortNumber: CHOOSE_PORT_MGM PortNumber: CHOOSE_PORT_MGM
......
...@@ -54,7 +54,7 @@ while test $# -gt 0; do ...@@ -54,7 +54,7 @@ while test $# -gt 0; do
stop_ndb=1 stop_ndb=1
;; ;;
--initial) --initial)
flags_ndb=$flags_ndb" -i" flags_ndb="$flags_ndb -i"
initial_ndb=1 initial_ndb=1
;; ;;
--status) --status)
...@@ -81,20 +81,18 @@ while test $# -gt 0; do ...@@ -81,20 +81,18 @@ while test $# -gt 0; do
shift shift
done done
fs_ndb=$fsdir/ndbcluster-$port_base fs_ndb="$fsdir/ndbcluster-$port_base"
fs_name_1=$fs_ndb/node-1-fs
fs_name_2=$fs_ndb/node-2-fs
NDB_HOME= NDB_HOME=
if [ ! -x $fsdir ]; then if [ ! -x "$fsdir" ]; then
echo "$fsdir missing" echo "$fsdir missing"
exit 1 exit 1
fi fi
if [ ! -x $exec_ndb ]; then if [ ! -x "$exec_ndb" ]; then
echo "$exec_ndb missing" echo "$exec_ndb missing"
exit 1 exit 1
fi fi
if [ ! -x $exec_mgmtsrvr ]; then if [ ! -x "$exec_mgmtsrvr" ]; then
echo "$exec_mgmtsrvr missing" echo "$exec_mgmtsrvr missing"
exit 1 exit 1
fi fi
...@@ -108,12 +106,10 @@ start_default_ndbcluster() { ...@@ -108,12 +106,10 @@ start_default_ndbcluster() {
# do some checks # do some checks
if [ $initial_ndb ] ; then if [ "$initial_ndb" ] ; then
[ -d $fs_ndb ] || mkdir $fs_ndb [ -d "$fs_ndb" ] || mkdir "$fs_ndb"
[ -d $fs_name_1 ] || mkdir $fs_name_1
[ -d $fs_name_2 ] || mkdir $fs_name_2
fi fi
if [ -d "$fs_ndb" -a -d "$fs_name_1" -a -d "$fs_name_2" ]; then :; else if [ -d "$fs_ndb" ]; then :; else
echo "$fs_ndb filesystem directory does not exist" echo "$fs_ndb filesystem directory does not exist"
exit 1 exit 1
fi fi
...@@ -128,42 +124,41 @@ port_transporter=`expr $ndb_mgmd_port + 2` ...@@ -128,42 +124,41 @@ port_transporter=`expr $ndb_mgmd_port + 2`
if [ $initial_ndb ] ; then if [ $initial_ndb ] ; then
sed \ sed \
-e s,"CHOOSE_MaxNoOfConcurrentOperations",$ndb_con_op,g \ -e s,"CHOOSE_MaxNoOfConcurrentOperations","$ndb_con_op",g \
-e s,"CHOOSE_DataMemory",$ndb_dmem,g \ -e s,"CHOOSE_DataMemory","$ndb_dmem",g \
-e s,"CHOOSE_IndexMemory",$ndb_imem,g \ -e s,"CHOOSE_IndexMemory","$ndb_imem",g \
-e s,"CHOOSE_Diskless",$ndb_diskless,g \ -e s,"CHOOSE_Diskless","$ndb_diskless",g \
-e s,"CHOOSE_HOSTNAME_".*,"$ndb_host",g \ -e s,"CHOOSE_HOSTNAME_".*,"$ndb_host",g \
-e s,"CHOOSE_FILESYSTEM_NODE_1","$fs_name_1",g \ -e s,"CHOOSE_FILESYSTEM","$fs_ndb",g \
-e s,"CHOOSE_FILESYSTEM_NODE_2","$fs_name_2",g \ -e s,"CHOOSE_PORT_MGM","$ndb_mgmd_port",g \
-e s,"CHOOSE_PORT_MGM",$ndb_mgmd_port,g \ -e s,"CHOOSE_PORT_TRANSPORTER","$port_transporter",g \
-e s,"CHOOSE_PORT_TRANSPORTER",$port_transporter,g \
< ndb/ndb_config_2_node.ini \ < ndb/ndb_config_2_node.ini \
> "$fs_ndb/config.ini" > "$fs_ndb/config.ini"
fi fi
rm -f $cfgfile 2>&1 | cat > /dev/null rm -f "$cfgfile" 2>&1 | cat > /dev/null
rm -f $fs_ndb/$cfgfile 2>&1 | cat > /dev/null rm -f "$fs_ndb/$cfgfile" 2>&1 | cat > /dev/null
if ( cd $fs_ndb ; $exec_mgmtsrvr -d -c config.ini ) ; then :; else if ( cd "$fs_ndb" ; $exec_mgmtsrvr -d -c config.ini ) ; then :; else
echo "Unable to start $exec_mgmtsrvr from `pwd`" echo "Unable to start $exec_mgmtsrvr from `pwd`"
exit 1 exit 1
fi fi
cat `find $fs_ndb -name 'ndb_*.pid'` > $fs_ndb/$pidfile cat `find "$fs_ndb" -name 'ndb_*.pid'` > "$fs_ndb/$pidfile"
# Start database node # Start database node
echo "Starting ndbd" echo "Starting ndbd"
( cd $fs_ndb ; $exec_ndb -d $flags_ndb & ) ( cd "$fs_ndb" ; $exec_ndb -d $flags_ndb & )
cat `find $fs_ndb -name 'ndb_*.pid'` > $fs_ndb/$pidfile cat `find "$fs_ndb" -name 'ndb_*.pid'` > "$fs_ndb/$pidfile"
# Start database node # Start database node
echo "Starting ndbd" echo "Starting ndbd"
( cd $fs_ndb ; $exec_ndb -d $flags_ndb & ) ( cd "$fs_ndb" ; $exec_ndb -d $flags_ndb & )
cat `find $fs_ndb -name 'ndb_*.pid'` > $fs_ndb/$pidfile cat `find "$fs_ndb" -name 'ndb_*.pid'` > "$fs_ndb/$pidfile"
# test if Ndb Cluster starts properly # test if Ndb Cluster starts properly
...@@ -173,7 +168,7 @@ if ( $exec_waiter ) | grep "NDBT_ProgramExit: 0 - OK"; then :; else ...@@ -173,7 +168,7 @@ if ( $exec_waiter ) | grep "NDBT_ProgramExit: 0 - OK"; then :; else
exit 1 exit 1
fi fi
cat `find $fs_ndb -name 'ndb_*.pid'` > $fs_ndb/$pidfile cat `find "$fs_ndb" -name 'ndb_*.pid'` > $fs_ndb/$pidfile
status_ndbcluster status_ndbcluster
} }
...@@ -200,9 +195,9 @@ exec_mgmtclient="$exec_mgmtclient --try-reconnect=1" ...@@ -200,9 +195,9 @@ exec_mgmtclient="$exec_mgmtclient --try-reconnect=1"
echo "all stop" | $exec_mgmtclient 2>&1 | cat > /dev/null echo "all stop" | $exec_mgmtclient 2>&1 | cat > /dev/null
if [ -f $fs_ndb/$pidfile ] ; then if [ -f "$fs_ndb/$pidfile" ] ; then
kill -9 `cat $fs_ndb/$pidfile` 2> /dev/null kill -9 `cat "$fs_ndb/$pidfile"` 2> /dev/null
rm $fs_ndb/$pidfile rm "$fs_ndb/$pidfile"
fi fi
} }
......
drop table if exists t1;
create table t1 (a int) engine=innodb;
begin;
insert into t1 values(1);
flush tables with read lock;
select * from t1;
a
commit;
select * from t1;
a
unlock tables;
begin;
select * from t1 for update;
a
1
begin;
select * from t1 for update;
flush tables with read lock;
commit;
a
1
unlock tables;
drop table t1;
# Let's see if FLUSH TABLES WITH READ LOCK blocks COMMIT of existing
# transactions.
# We verify that we did not introduce a deadlock.
-- source include/have_innodb.inc
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connect (con3,localhost,root,,);
connection con1;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int) engine=innodb;
# blocks COMMIT ?
begin;
insert into t1 values(1);
connection con2;
flush tables with read lock;
select * from t1;
connection con1;
send commit; # blocked by con2
sleep 1;
connection con2;
select * from t1; # verify con1 was blocked and data did not move
unlock tables;
connection con1;
reap;
# No deadlock ?
connection con1;
begin;
select * from t1 for update;
connection con2;
begin;
send select * from t1 for update; # blocked by con1
sleep 1;
connection con3;
send flush tables with read lock; # blocked by con2
connection con1;
commit; # should not be blocked by con3
connection con2;
reap;
connection con3;
reap;
unlock tables;
connection con1;
drop table t1;
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <NdbTCP.h>
#include "ConfigInfo.hpp" #include "ConfigInfo.hpp"
#include <mgmapi_config_parameters.h> #include <mgmapi_config_parameters.h>
#include <ndb_limits.h> #include <ndb_limits.h>
...@@ -48,24 +49,25 @@ sizeof(m_sectionNames)/sizeof(char*); ...@@ -48,24 +49,25 @@ sizeof(m_sectionNames)/sizeof(char*);
/**************************************************************************** /****************************************************************************
* Section Rules declarations * Section Rules declarations
****************************************************************************/ ****************************************************************************/
bool transformComputer(InitConfigFileParser::Context & ctx, const char *); static bool transformComputer(InitConfigFileParser::Context & ctx, const char *);
bool transformSystem(InitConfigFileParser::Context & ctx, const char *); static bool transformSystem(InitConfigFileParser::Context & ctx, const char *);
bool transformExternalSystem(InitConfigFileParser::Context & ctx, const char *); static bool transformExternalSystem(InitConfigFileParser::Context & ctx, const char *);
bool transformNode(InitConfigFileParser::Context & ctx, const char *); static bool transformNode(InitConfigFileParser::Context & ctx, const char *);
bool transformExtNode(InitConfigFileParser::Context & ctx, const char *); static bool transformExtNode(InitConfigFileParser::Context & ctx, const char *);
bool transformConnection(InitConfigFileParser::Context & ctx, const char *); static bool transformConnection(InitConfigFileParser::Context & ctx, const char *);
bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *); static bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *);
bool checkMandatory(InitConfigFileParser::Context & ctx, const char *); static bool checkMandatory(InitConfigFileParser::Context & ctx, const char *);
bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *); static bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *);
bool fixShmkey(InitConfigFileParser::Context & ctx, const char *); static bool fixShmkey(InitConfigFileParser::Context & ctx, const char *);
bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *); static bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *);
bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *); static bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *);
bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data); static bool checkTCPConstraints(InitConfigFileParser::Context &, const char *);
bool fixHostname(InitConfigFileParser::Context & ctx, const char * data); static bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data);
bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data); static bool fixHostname(InitConfigFileParser::Context & ctx, const char * data);
bool fixExtConnection(InitConfigFileParser::Context & ctx, const char * data); static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data);
bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); static bool fixExtConnection(InitConfigFileParser::Context & ctx, const char * data);
bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *);
static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *);
const ConfigInfo::SectionRule const ConfigInfo::SectionRule
ConfigInfo::m_SectionRules[] = { ConfigInfo::m_SectionRules[] = {
...@@ -130,7 +132,9 @@ ConfigInfo::m_SectionRules[] = { ...@@ -130,7 +132,9 @@ ConfigInfo::m_SectionRules[] = {
{ "SCI", checkConnectionConstraints, 0 }, { "SCI", checkConnectionConstraints, 0 },
{ "OSE", checkConnectionConstraints, 0 }, { "OSE", checkConnectionConstraints, 0 },
{ "TCP", checkTCPConstraints, "HostName1" },
{ "TCP", checkTCPConstraints, "HostName2" },
{ "*", checkMandatory, 0 }, { "*", checkMandatory, 0 },
{ "DB", saveInConfigValues, 0 }, { "DB", saveInConfigValues, 0 },
...@@ -148,13 +152,13 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); ...@@ -148,13 +152,13 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
/**************************************************************************** /****************************************************************************
* Config Rules declarations * Config Rules declarations
****************************************************************************/ ****************************************************************************/
bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections, static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data); const char * rule_data);
bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections, static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data); const char * rule_data);
bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections, static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data); const char * rule_data);
...@@ -812,7 +816,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ...@@ -812,7 +816,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
1}, 1},
{ {
CFG_DB_DISCLESS, KEY_INTERNAL,
"Discless", "Discless",
"DB", "DB",
"Diskless", "Diskless",
...@@ -2219,22 +2223,13 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2219,22 +2223,13 @@ fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){
require(ctx.m_currentSection->put("HostName", "")); require(ctx.m_currentSection->put("HostName", ""));
const char * type; const char * type;
if(ctx.m_currentSection->get("Type", &type) && if(ctx.m_currentSection->get("Type", &type) && strcmp(type,"DB") == 0) {
strcmp(type,"DB") == 0) ctx.reportError("Parameter \"ExecuteOnComputer\" missing from DB section"
{ " [%s] starting at line: %d",
ctx.reportError("Parameter \"ExecuteOnComputer\" missing from DB section " ctx.fname, ctx.m_sectionLineno);
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false; return false;
} }
return true; return true;
#if 0
ctx.reportError("Parameter \"ExecuteOnComputer\" missing from section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
#endif
} }
const Properties * computer; const Properties * computer;
...@@ -2362,6 +2357,22 @@ transformComputer(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2362,6 +2357,22 @@ transformComputer(InitConfigFileParser::Context & ctx, const char * data){
ctx.m_userProperties.get("NoOfComputers", &computers); ctx.m_userProperties.get("NoOfComputers", &computers);
ctx.m_userProperties.put("NoOfComputers", ++computers, true); ctx.m_userProperties.put("NoOfComputers", ++computers, true);
const char * hostname = 0;
ctx.m_currentSection->get("HostName", &hostname);
if(!hostname){
return true;
}
if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){
if(ctx.m_userProperties.get("$computer-localhost", &hostname)){
ctx.reportError("Mixing of localhost with other hostname(%s) is illegal",
hostname);
return false;
}
} else {
ctx.m_userProperties.put("$computer-localhost", hostname);
}
return true; return true;
} }
...@@ -2449,7 +2460,7 @@ checkMandatory(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2449,7 +2460,7 @@ checkMandatory(InitConfigFileParser::Context & ctx, const char * data){
* Transform a string "NodeidX" (e.g. "uppsala.32") * Transform a string "NodeidX" (e.g. "uppsala.32")
* into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala"). * into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala").
*/ */
bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data) static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data)
{ {
char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")]; char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")];
char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")]; char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")];
...@@ -2485,7 +2496,7 @@ bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data) ...@@ -2485,7 +2496,7 @@ bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data)
* - name of external system in parameter extSystemName, and * - name of external system in parameter extSystemName, and
* - nodeId of external node in parameter extSystemNodeId. * - nodeId of external node in parameter extSystemNodeId.
*/ */
bool static bool
isExtConnection(InitConfigFileParser::Context & ctx, isExtConnection(InitConfigFileParser::Context & ctx,
const char **extSystemName, Uint32 * extSystemNodeId){ const char **extSystemName, Uint32 * extSystemNodeId){
...@@ -2513,7 +2524,7 @@ isExtConnection(InitConfigFileParser::Context & ctx, ...@@ -2513,7 +2524,7 @@ isExtConnection(InitConfigFileParser::Context & ctx,
* If connection is to an external system, then move connection into * If connection is to an external system, then move connection into
* external system configuration (i.e. a sub-property). * external system configuration (i.e. a sub-property).
*/ */
bool static bool
fixExtConnection(InitConfigFileParser::Context & ctx, const char * data){ fixExtConnection(InitConfigFileParser::Context & ctx, const char * data){
const char * extSystemName; const char * extSystemName;
...@@ -2568,7 +2579,7 @@ fixExtConnection(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2568,7 +2579,7 @@ fixExtConnection(InitConfigFileParser::Context & ctx, const char * data){
* -# Via Node's ExecuteOnComputer lookup Hostname * -# Via Node's ExecuteOnComputer lookup Hostname
* -# Add HostName to Connection * -# Add HostName to Connection
*/ */
bool static bool
fixHostname(InitConfigFileParser::Context & ctx, const char * data){ fixHostname(InitConfigFileParser::Context & ctx, const char * data){
char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")]; char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")];
...@@ -2591,7 +2602,7 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2591,7 +2602,7 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){
/** /**
* Connection rule: Fix port number (using a port number adder) * Connection rule: Fix port number (using a port number adder)
*/ */
bool static bool
fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
Uint32 id1= 0, id2= 0; Uint32 id1= 0, id2= 0;
...@@ -2645,7 +2656,7 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2645,7 +2656,7 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
/** /**
* DB Node rule: Check various constraints * DB Node rule: Check various constraints
*/ */
bool static bool
checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){ checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){
Uint32 t1 = 0, t2 = 0; Uint32 t1 = 0, t2 = 0;
...@@ -2678,7 +2689,7 @@ checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){ ...@@ -2678,7 +2689,7 @@ checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){
/** /**
* Connection rule: Check varius constraints * Connection rule: Check varius constraints
*/ */
bool static bool
checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){
Uint32 id1 = 0, id2 = 0; Uint32 id1 = 0, id2 = 0;
...@@ -2734,6 +2745,22 @@ checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ ...@@ -2734,6 +2745,22 @@ checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){
ctx.fname, ctx.m_sectionLineno); ctx.fname, ctx.m_sectionLineno);
return false; return false;
} }
return true;
}
static bool
checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){
const char * host;
struct in_addr addr;
if(ctx.m_currentSection->get(data, &host) && strlen(host) &&
Ndb_getInAddr(&addr, host)){
ctx.reportError("Unable to lookup/illegal hostname %s"
" - [%s] starting at line: %d",
host, ctx.fname, ctx.m_sectionLineno);
return false;
}
return true; return true;
} }
...@@ -2777,15 +2804,15 @@ transform(InitConfigFileParser::Context & ctx, ...@@ -2777,15 +2804,15 @@ transform(InitConfigFileParser::Context & ctx,
return false; return false;
} }
if(newType == ConfigInfo::INT){ if(newType == ConfigInfo::INT || newType == ConfigInfo::BOOL){
require(dst.put(newName, (Uint32)newVal)); require(dst.put(newName, (Uint32)newVal));
} else { } else if(newType == ConfigInfo::INT64) {
require(dst.put64(newName, newVal)); require(dst.put64(newName, newVal));
} }
return true; return true;
} }
bool static bool
fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
const char * name; const char * name;
/** /**
...@@ -2845,7 +2872,7 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2845,7 +2872,7 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
return true; return true;
} }
bool static bool
saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
const Properties * sec; const Properties * sec;
if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ if(!ctx.m_currentInfo->get(ctx.fname, &sec)){
...@@ -2910,13 +2937,14 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ ...@@ -2910,13 +2937,14 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
default: default:
abort(); abort();
} }
require(ok);
} }
ctx.m_configValues.closeSection(); ctx.m_configValues.closeSection();
} while(0); } while(0);
return true; return true;
} }
bool static bool
add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections, add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data) const char * rule_data)
...@@ -3003,7 +3031,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections, ...@@ -3003,7 +3031,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
} }
bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections, static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data) const char * rule_data)
{ {
...@@ -3042,7 +3070,7 @@ bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections, ...@@ -3042,7 +3070,7 @@ bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>&sections,
return true; return true;
} }
bool static bool
check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections, check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx, struct InitConfigFileParser::Context &ctx,
const char * rule_data) const char * rule_data)
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <mgmapi.h> #include <mgmapi.h>
#include <mgmapi_config_parameters.h> #include <mgmapi_config_parameters.h>
#include <mgmapi_configuration.hpp>
#include <ConfigValues.hpp> #include <ConfigValues.hpp>
#include <NdbHost.h> #include <NdbHost.h>
...@@ -267,7 +268,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf){ ...@@ -267,7 +268,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf){
char localhost[MAXHOSTNAMELEN]; char localhost[MAXHOSTNAMELEN];
if(NdbHost_GetHostName(localhost) != 0){ if(NdbHost_GetHostName(localhost) != 0){
snprintf(buf, 255, "Unable to own hostname"); snprintf(buf, 255, "Unable to get own hostname");
setError(CR_ERROR, buf); setError(CR_ERROR, buf);
return false; return false;
} }
...@@ -317,6 +318,46 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf){ ...@@ -317,6 +318,46 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf){
return false; return false;
} }
/**
* Check hostnames
*/
ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
for(iter.first(); iter.valid(); iter.next()){
Uint32 type = CONNECTION_TYPE_TCP + 1;
if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
if(type != CONNECTION_TYPE_TCP) continue;
Uint32 nodeId1, nodeId2, remoteNodeId;
if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;
if(nodeId1 != _ownNodeId && nodeId2 != _ownNodeId) continue;
remoteNodeId = (_ownNodeId == nodeId1 ? nodeId2 : nodeId1);
const char * name;
struct in_addr addr;
BaseString tmp;
if(!iter.get(CFG_TCP_HOSTNAME_1, &name) && strlen(name)){
if(Ndb_getInAddr(&addr, name) != 0){
tmp.assfmt("Unable to lookup/illegal hostname %s, "
"connection from node %d to node %d",
name, _ownNodeId, remoteNodeId);
setError(CR_ERROR, tmp.c_str());
return false;
}
}
if(!iter.get(CFG_TCP_HOSTNAME_2, &name) && strlen(name)){
if(Ndb_getInAddr(&addr, name) != 0){
tmp.assfmt("Unable to lookup/illegal hostname %s, "
"connection from node %d to node %d",
name, _ownNodeId, remoteNodeId);
setError(CR_ERROR, tmp.c_str());
return false;
}
}
}
return true; return true;
} }
......
...@@ -108,8 +108,8 @@ AsyncFile::AsyncFile() : ...@@ -108,8 +108,8 @@ AsyncFile::AsyncFile() :
} }
void void
AsyncFile::doStart(const char * filesystemPath) { AsyncFile::doStart(Uint32 nodeId, const char * filesystemPath) {
theFileName.init(filesystemPath); theFileName.init(nodeId, filesystemPath);
// Stacksize for filesystem threads // Stacksize for filesystem threads
// An 8k stack should be enough // An 8k stack should be enough
......
...@@ -181,7 +181,7 @@ public: ...@@ -181,7 +181,7 @@ public:
void execute( Request* request ); void execute( Request* request );
void doStart(const char * fspath); void doStart(Uint32 nodeId, const char * fspath);
// its a thread so its always running // its a thread so its always running
void run(); void run();
......
...@@ -46,7 +46,7 @@ Filename::Filename() : ...@@ -46,7 +46,7 @@ Filename::Filename() :
} }
void void
Filename::init(const char * pFileSystemPath){ Filename::init(Uint32 nodeid, const char * pFileSystemPath){
if (pFileSystemPath == NULL) { if (pFileSystemPath == NULL) {
ERROR_SET(fatal, AFS_ERROR_NOPATH, ""," Filename::init()"); ERROR_SET(fatal, AFS_ERROR_NOPATH, ""," Filename::init()");
return; return;
...@@ -75,8 +75,15 @@ Filename::init(const char * pFileSystemPath){ ...@@ -75,8 +75,15 @@ Filename::init(const char * pFileSystemPath){
DIR_SEPARATOR) != 0) DIR_SEPARATOR) != 0)
strcat(theBaseDirectory, DIR_SEPARATOR); strcat(theBaseDirectory, DIR_SEPARATOR);
} snprintf(buf2, sizeof(buf2), "ndb_%u_fs%s", nodeid, DIR_SEPARATOR);
strcat(theBaseDirectory, buf2);
#ifdef NDB_WIN32
CreateDirectory(theBaseDirectory, 0);
#else
mkdir(theBaseDirectory, S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
#endif
}
Filename::~Filename(){ Filename::~Filename(){
} }
......
...@@ -68,7 +68,7 @@ public: ...@@ -68,7 +68,7 @@ public:
int levels() const; int levels() const;
const char* c_str() const; const char* c_str() const;
void init(const char * fileSystemPath); void init(Uint32 nodeid, const char * fileSystemPath);
private: private:
int theLevelDepth; int theLevelDepth;
......
...@@ -559,7 +559,7 @@ Ndbfs::createAsyncFile(){ ...@@ -559,7 +559,7 @@ Ndbfs::createAsyncFile(){
} }
AsyncFile* file = new AsyncFile; AsyncFile* file = new AsyncFile;
file->doStart(theFileSystemPath); file->doStart(getOwnNodeId(), theFileSystemPath);
// Put the file in list of all files // Put the file in list of all files
theFiles.push_back(file); theFiles.push_back(file);
......
...@@ -309,11 +309,12 @@ catchsigs(bool ignore){ ...@@ -309,11 +309,12 @@ catchsigs(bool ignore){
SIGPIPE SIGPIPE
}; };
for(size_t i = 0; i < sizeof(signals_shutdown)/sizeof(signals_shutdown[0]); i++) size_t i;
for(i = 0; i < sizeof(signals_shutdown)/sizeof(signals_shutdown[0]); i++)
handler_register(signals_shutdown[i], handler_shutdown, ignore); handler_register(signals_shutdown[i], handler_shutdown, ignore);
for(size_t i = 0; i < sizeof(signals_error)/sizeof(signals_error[0]); i++) for(i = 0; i < sizeof(signals_error)/sizeof(signals_error[0]); i++)
handler_register(signals_error[i], handler_error, ignore); handler_register(signals_error[i], handler_error, ignore);
for(size_t i = 0; i < sizeof(signals_ignore)/sizeof(signals_ignore[0]); i++) for(i = 0; i < sizeof(signals_ignore)/sizeof(signals_ignore[0]); i++)
handler_register(signals_ignore[i], SIG_IGN, ignore); handler_register(signals_ignore[i], SIG_IGN, ignore);
} }
......
...@@ -30,7 +30,6 @@ noinst_PROGRAMS = gen_lex_hash ...@@ -30,7 +30,6 @@ noinst_PROGRAMS = gen_lex_hash
bin_PROGRAMS = mysql_tzinfo_to_sql bin_PROGRAMS = mysql_tzinfo_to_sql
gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
LDADD = @isam_libs@ \ LDADD = @isam_libs@ \
@ZLIB_LIBS@ \
$(top_builddir)/myisam/libmyisam.a \ $(top_builddir)/myisam/libmyisam.a \
$(top_builddir)/myisammrg/libmyisammrg.a \ $(top_builddir)/myisammrg/libmyisammrg.a \
$(top_builddir)/heap/libheap.a \ $(top_builddir)/heap/libheap.a \
...@@ -38,7 +37,7 @@ LDADD = @isam_libs@ \ ...@@ -38,7 +37,7 @@ LDADD = @isam_libs@ \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \ $(top_builddir)/dbug/libdbug.a \
$(top_builddir)/regex/libregex.a \ $(top_builddir)/regex/libregex.a \
$(top_builddir)/strings/libmystrings.a $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
@bdb_libs@ @innodb_libs@ @pstack_libs@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \
......
...@@ -476,27 +476,41 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -476,27 +476,41 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
if (opt_using_transactions) if (opt_using_transactions)
{ {
bool operation_done= 0;
bool transaction_commited= 0; bool transaction_commited= 0;
bool operation_done= 0, need_start_waiters= 0;
/* Update the binary log if we have cached some queries */ /* If transaction has done some updates to tables */
if (trans == &thd->transaction.all && mysql_bin_log.is_open() && if (trans == &thd->transaction.all &&
my_b_tell(&thd->transaction.trans_log)) my_b_tell(&thd->transaction.trans_log))
{ {
mysql_bin_log.write(thd, &thd->transaction.trans_log, 1); if (error= wait_if_global_read_lock(thd, 0, 0))
statistic_increment(binlog_cache_use, &LOCK_status);
if (thd->transaction.trans_log.disk_writes != 0)
{ {
/* /*
We have to do this after addition of trans_log to main binlog since Note that ROLLBACK [TO SAVEPOINT] does not have this test; it's
this operation can cause flushing of end of trans_log to disk. because ROLLBACK never updates data, so needn't wait on the lock.
*/ */
statistic_increment(binlog_cache_disk_use, &LOCK_status); my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
thd->transaction.trans_log.disk_writes= 0; error= 1;
}
else
need_start_waiters= 1;
if (mysql_bin_log.is_open())
{
mysql_bin_log.write(thd, &thd->transaction.trans_log, 1);
statistic_increment(binlog_cache_use, &LOCK_status);
if (thd->transaction.trans_log.disk_writes != 0)
{
/*
We have to do this after addition of trans_log to main binlog since
this operation can cause flushing of end of trans_log to disk.
*/
statistic_increment(binlog_cache_disk_use, &LOCK_status);
thd->transaction.trans_log.disk_writes= 0;
}
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
} }
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
} }
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
if (trans->ndb_tid) if (trans->ndb_tid)
...@@ -551,6 +565,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -551,6 +565,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
statistic_increment(ha_commit_count,&LOCK_status); statistic_increment(ha_commit_count,&LOCK_status);
thd->transaction.cleanup(); thd->transaction.cleanup();
} }
if (need_start_waiters)
start_waiting_global_read_lock(thd);
} }
#endif // using transactions #endif // using transactions
DBUG_RETURN(error); DBUG_RETURN(error);
......
...@@ -99,7 +99,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count) ...@@ -99,7 +99,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
Wait until the lock is gone Wait until the lock is gone
*/ */
if (wait_if_global_read_lock(thd, 1)) if (wait_if_global_read_lock(thd, 1, 1))
{ {
my_free((gptr) sql_lock,MYF(0)); my_free((gptr) sql_lock,MYF(0));
sql_lock=0; sql_lock=0;
...@@ -474,7 +474,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) ...@@ -474,7 +474,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
int error= -1; int error= -1;
DBUG_ENTER("lock_and_wait_for_table_name"); DBUG_ENTER("lock_and_wait_for_table_name");
if (wait_if_global_read_lock(thd,0)) if (wait_if_global_read_lock(thd, 0, 1))
DBUG_RETURN(1); DBUG_RETURN(1);
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if ((lock_retcode = lock_table_name(thd, table_list)) < 0) if ((lock_retcode = lock_table_name(thd, table_list)) < 0)
...@@ -707,14 +707,23 @@ static void print_lock_error(int error) ...@@ -707,14 +707,23 @@ static void print_lock_error(int error)
The global locks are handled through the global variables: The global locks are handled through the global variables:
global_read_lock global_read_lock
global_read_lock_blocks_commit
waiting_for_read_lock waiting_for_read_lock
protect_against_global_read_lock protect_against_global_read_lock
Taking the global read lock is TWO steps (2nd step is optional; without
it, COMMIT of existing transactions will be allowed):
lock_global_read_lock() THEN make_global_read_lock_block_commit().
****************************************************************************/ ****************************************************************************/
volatile uint global_read_lock=0; volatile uint global_read_lock=0;
volatile uint global_read_lock_blocks_commit=0;
static volatile uint protect_against_global_read_lock=0; static volatile uint protect_against_global_read_lock=0;
static volatile uint waiting_for_read_lock=0; static volatile uint waiting_for_read_lock=0;
#define GOT_GLOBAL_READ_LOCK 1
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
bool lock_global_read_lock(THD *thd) bool lock_global_read_lock(THD *thd)
{ {
DBUG_ENTER("lock_global_read_lock"); DBUG_ENTER("lock_global_read_lock");
...@@ -737,27 +746,40 @@ bool lock_global_read_lock(THD *thd) ...@@ -737,27 +746,40 @@ bool lock_global_read_lock(THD *thd)
thd->exit_cond(old_message); thd->exit_cond(old_message);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
thd->global_read_lock=1; thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
global_read_lock++; global_read_lock++;
thd->exit_cond(old_message); thd->exit_cond(old_message);
} }
/*
We DON'T set global_read_lock_blocks_commit now, it will be set after
tables are flushed (as the present function serves for FLUSH TABLES WITH
READ LOCK only). Doing things in this order is necessary to avoid
deadlocks (we must allow COMMIT until all tables are closed; we should not
forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
UPDATE and one does FLUSH TABLES WITH READ LOCK).
*/
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void unlock_global_read_lock(THD *thd) void unlock_global_read_lock(THD *thd)
{ {
uint tmp; uint tmp;
thd->global_read_lock=0;
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
tmp= --global_read_lock; tmp= --global_read_lock;
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
--global_read_lock_blocks_commit;
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
/* Send the signal outside the mutex to avoid a context switch */ /* Send the signal outside the mutex to avoid a context switch */
if (!tmp) if (!tmp)
pthread_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_refresh);
thd->global_read_lock= 0;
} }
#define must_wait (global_read_lock && \
(is_not_commit || \
global_read_lock_blocks_commit))
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit)
{ {
const char *old_message; const char *old_message;
bool result= 0, need_exit_cond; bool result= 0, need_exit_cond;
...@@ -765,7 +787,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) ...@@ -765,7 +787,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
LINT_INIT(old_message); LINT_INIT(old_message);
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_open);
if (need_exit_cond= (bool)global_read_lock) if (need_exit_cond= must_wait)
{ {
if (thd->global_read_lock) // This thread had the read locks if (thd->global_read_lock) // This thread had the read locks
{ {
...@@ -775,7 +797,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) ...@@ -775,7 +797,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
} }
old_message=thd->enter_cond(&COND_refresh, &LOCK_open, old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
"Waiting for release of readlock"); "Waiting for release of readlock");
while (global_read_lock && ! thd->killed && while (must_wait && ! thd->killed &&
(!abort_on_refresh || thd->version == refresh_version)) (!abort_on_refresh || thd->version == refresh_version))
(void) pthread_cond_wait(&COND_refresh,&LOCK_open); (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
if (thd->killed) if (thd->killed)
...@@ -802,3 +824,21 @@ void start_waiting_global_read_lock(THD *thd) ...@@ -802,3 +824,21 @@ void start_waiting_global_read_lock(THD *thd)
pthread_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_refresh);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void make_global_read_lock_block_commit(THD *thd)
{
/*
If we didn't succeed lock_global_read_lock(), or if we already suceeded
make_global_read_lock_block_commit(), do nothing.
*/
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
return;
pthread_mutex_lock(&LOCK_open);
/* increment this BEFORE waiting on cond (otherwise race cond) */
global_read_lock_blocks_commit++;
while (protect_against_global_read_lock)
pthread_cond_wait(&COND_refresh, &LOCK_open);
pthread_mutex_unlock(&LOCK_open);
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
}
...@@ -828,7 +828,6 @@ extern Gt_creator gt_creator; ...@@ -828,7 +828,6 @@ extern Gt_creator gt_creator;
extern Lt_creator lt_creator; extern Lt_creator lt_creator;
extern Ge_creator ge_creator; extern Ge_creator ge_creator;
extern Le_creator le_creator; extern Le_creator le_creator;
extern uchar days_in_month[];
extern char language[LIBLEN],reg_ext[FN_EXTLEN]; extern char language[LIBLEN],reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file; extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
...@@ -955,8 +954,9 @@ void mysql_lock_abort_for_thread(THD *thd, TABLE *table); ...@@ -955,8 +954,9 @@ void mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
bool lock_global_read_lock(THD *thd); bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh); bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit);
void start_waiting_global_read_lock(THD *thd); void start_waiting_global_read_lock(THD *thd);
void make_global_read_lock_block_commit(THD *thd);
/* Lock based on name */ /* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list); int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
......
...@@ -812,7 +812,7 @@ public: ...@@ -812,7 +812,7 @@ public:
ulong row_count; // Row counter, mainly for errors and warnings ulong row_count; // Row counter, mainly for errors and warnings
long dbug_thread_id; long dbug_thread_id;
pthread_t real_id; pthread_t real_id;
uint current_tablenr,tmp_table; uint current_tablenr,tmp_table,global_read_lock;
uint server_status,open_options,system_thread; uint server_status,open_options,system_thread;
uint32 db_length; uint32 db_length;
uint select_number; //number of select (used for EXPLAIN) uint select_number; //number of select (used for EXPLAIN)
...@@ -831,7 +831,7 @@ public: ...@@ -831,7 +831,7 @@ public:
bool no_errors, password, is_fatal_error; bool no_errors, password, is_fatal_error;
bool query_start_used,last_insert_id_used,insert_id_used,rand_used; bool query_start_used,last_insert_id_used,insert_id_used,rand_used;
bool time_zone_used; bool time_zone_used;
bool in_lock_tables,global_read_lock; bool in_lock_tables;
bool query_error, bootstrap, cleanup_done; bool query_error, bootstrap, cleanup_done;
bool tmp_table_used; bool tmp_table_used;
bool charset_is_system_charset, charset_is_collation_connection; bool charset_is_system_charset, charset_is_collation_connection;
......
...@@ -396,7 +396,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -396,7 +396,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not create database if another thread is holding read lock // do not create database if another thread is holding read lock
if (wait_if_global_read_lock(thd,0)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
...@@ -498,7 +498,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) ...@@ -498,7 +498,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not alter database if another thread is holding read lock // do not alter database if another thread is holding read lock
if ((error=wait_if_global_read_lock(thd,0))) if ((error=wait_if_global_read_lock(thd,0,1)))
goto exit2; goto exit2;
/* Check directory */ /* Check directory */
...@@ -565,7 +565,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -565,7 +565,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
// do not drop database if another thread is holding read lock // do not drop database if another thread is holding read lock
if (wait_if_global_read_lock(thd,0)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
......
...@@ -4815,9 +4815,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, ...@@ -4815,9 +4815,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
tmp_write_to_binlog= 0; tmp_write_to_binlog= 0;
if (lock_global_read_lock(thd)) if (lock_global_read_lock(thd))
return 1; return 1;
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1,
tables);
make_global_read_lock_block_commit(thd);
} }
else
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
my_dbopt_cleanup(); my_dbopt_cleanup();
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
} }
if (options & REFRESH_HOSTS) if (options & REFRESH_HOSTS)
hostname_cache_refresh(); hostname_cache_refresh();
......
...@@ -48,7 +48,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) ...@@ -48,7 +48,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (wait_if_global_read_lock(thd,0)) if (wait_if_global_read_lock(thd,0,1))
DBUG_RETURN(1); DBUG_RETURN(1);
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (lock_table_names(thd, table_list)) if (lock_table_names(thd, table_list))
......
...@@ -7999,7 +7999,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, ...@@ -7999,7 +7999,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
if (!item) if (!item)
return 1; return 1;
if (item != not_found_item) if (item != (Item **)not_found_item)
{ {
order->item= ref_pointer_array + counter; order->item= ref_pointer_array + counter;
order->in_field_list=1; order->in_field_list=1;
......
...@@ -1206,7 +1206,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -1206,7 +1206,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (wait_if_global_read_lock(thd, 0)) if (wait_if_global_read_lock(thd, 0, 1))
DBUG_RETURN(error); DBUG_RETURN(error);
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
......
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