From: magnus.blaudd Date: November 12 2012 3:04pm Subject: bzr push into mysql-trunk-cluster branch (magnus.blaudd:3567 to 3568) List-Archive: http://lists.mysql.com/commits/145244 Message-Id: <20121112150437.18434.80119.3568@wholphin> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3568 magnus.blaudd@stripped 2012-11-12 [merge] Merge 7.3 -> trunk-cluster modified: sql/ha_ndbcluster.cc sql/ha_ndbcluster_glue.h storage/ndb/cmake/os/Windows.cmake storage/ndb/compile-cluster storage/ndb/include/kernel/signaldata/LCP.hpp storage/ndb/include/mgmapi/mgmapi.h storage/ndb/memcache/include/int3korr.h storage/ndb/src/common/debugger/signaldata/LCP.cpp storage/ndb/src/kernel/blocks/backup/Backup.cpp storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp storage/ndb/src/mgmsrv/testConfig.cpp storage/ndb/test/ndbapi/testInterpreter.cpp 3567 magnus.blaudd@stripped 2012-11-12 ndb - fix unintentional(mystery) revert of some disabled.def files for ndb modified: mysql-test/suite/ndb/t/disabled.def mysql-test/suite/ndb_memcache/t/disabled.def mysql-test/suite/rpl_ndb/t/disabled.def === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2012-11-06 14:16:49 +0000 +++ b/sql/ha_ndbcluster.cc 2012-11-12 15:03:21 +0000 @@ -8982,8 +8982,7 @@ static int create_ndb_column(THD *thd, } else col.setAutoIncrement(FALSE); - -#ifndef NDB_WITHOUT_COLUMN_FORMAT + DBUG_PRINT("info", ("storage: %u format: %u ", field->field_storage_type(), field->column_format())); @@ -9018,7 +9017,6 @@ static int create_ndb_column(THD *thd, dynamic= (create_info->row_type == ROW_TYPE_DYNAMIC); break; } -#endif DBUG_PRINT("info", ("Column %s is declared %s", field->field_name, (dynamic) ? "dynamic" : "static")); if (type == NDBCOL::StorageTypeDisk) @@ -9030,7 +9028,6 @@ static int create_ndb_column(THD *thd, dynamic= false; } -#ifndef NDB_WITHOUT_COLUMN_FORMAT if (thd && field->column_format() == COLUMN_FORMAT_TYPE_DYNAMIC) { push_warning_printf(thd, Sql_condition::SL_WARNING, @@ -9040,7 +9037,6 @@ static int create_ndb_column(THD *thd, "column will become FIXED", field->field_name); } -#endif } switch (create_info->row_type) { @@ -9537,7 +9533,6 @@ int ha_ndbcluster::create(const char *na KEY_PART_INFO *end= key_part + key_info->user_defined_key_parts; for (; key_part != end; key_part++) { -#ifndef NDB_WITHOUT_COLUMN_FORMAT if (key_part->field->field_storage_type() == HA_SM_DISK) { push_warning_printf(thd, Sql_condition::SL_WARNING, @@ -9550,7 +9545,6 @@ int ha_ndbcluster::create(const char *na result= HA_ERR_UNSUPPORTED; goto abort_return; } -#endif tab.getColumn(key_part->fieldnr-1)->setStorageType( NdbDictionary::Column::StorageTypeMemory); } @@ -9990,7 +9984,6 @@ int ha_ndbcluster::create_ndb_index(THD for (; key_part != end; key_part++) { Field *field= key_part->field; -#ifndef NDB_WITHOUT_COLUMN_FORMAT if (field->field_storage_type() == HA_SM_DISK) { push_warning_printf(thd, Sql_condition::SL_WARNING, @@ -10002,7 +9995,6 @@ int ha_ndbcluster::create_ndb_index(THD "STORAGE DISK is not supported"); DBUG_RETURN(HA_ERR_UNSUPPORTED); } -#endif DBUG_PRINT("info", ("attr: %s", field->field_name)); if (ndb_index.addColumnName(field->field_name)) { === modified file 'sql/ha_ndbcluster_glue.h' --- a/sql/ha_ndbcluster_glue.h 2012-11-01 11:46:09 +0000 +++ b/sql/ha_ndbcluster_glue.h 2012-11-12 15:03:21 +0000 @@ -77,19 +77,12 @@ bool close_cached_tables(THD *thd, TABLE #endif - -extern ulong opt_server_id_mask; - static inline uint32 thd_unmasked_server_id(const THD* thd) { -#ifndef NDB_WITHOUT_SERVER_ID_BITS const uint32 unmasked_server_id = thd->unmasked_server_id; assert(thd->server_id == (thd->unmasked_server_id & opt_server_id_mask)); return unmasked_server_id; -#else - return thd->server_id; -#endif } === modified file 'storage/ndb/cmake/os/Windows.cmake' --- a/storage/ndb/cmake/os/Windows.cmake 2011-05-24 08:45:38 +0000 +++ b/storage/ndb/cmake/os/Windows.cmake 2012-11-12 10:58:00 +0000 @@ -21,3 +21,9 @@ GET_FILENAME_COMPONENT(_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) INCLUDE(${_SCRIPT_DIR}/WindowsCache.cmake) +IF(MSVC) + # Enable "Full Path of Source Code File in Diagnostics" to avoid + # "guessing" which file was causing warnings or error + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FC") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /FC") +ENDIF() === modified file 'storage/ndb/compile-cluster' --- a/storage/ndb/compile-cluster 2012-11-06 14:08:41 +0000 +++ b/storage/ndb/compile-cluster 2012-11-12 14:57:58 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -35,6 +35,8 @@ my $opt_build_type; my $opt_build = 1; my $opt_just_print; my $opt_vanilla; +my $opt_autotest; +my $opt_parse_log; Getopt::Long::Configure("pass_through"); GetOptions( @@ -46,6 +48,12 @@ GetOptions( 'c|just-configure' => sub { $opt_build = 0; }, 'n|just-print' => \$opt_just_print, 'vanilla' => \$opt_vanilla, + + 'autotest' => \$opt_autotest, + + # Special switch --parse-log= which reads a log file (from build) and + # parses it for warnings + 'parse-log=s' => \$opt_parse_log, ) or exit(1); # Find source root directory, assume this script is @@ -59,6 +67,23 @@ if ($^O eq "cygwin") { chomp $opt_srcdir; } +# Parse given log file for warnings +if ($opt_parse_log) +{ + use IO::File; + my $file = IO::File->new($opt_parse_log, 'r') + or die "Failed to open file $opt_parse_log: $!"; + my $parser = WarningParser->new(srcdir => $opt_srcdir, + unified => 1, + verbose => 1); + while (my $line = <$file>) + { + $parser->parse_line($line); + } + $parser->report($0); + exit(0); +} + # Check that cmake exists and figure out it's version my $cmake_version_id; { @@ -124,6 +149,12 @@ if(defined $ENV{"CXXFLAGS"} and $ENV{"CX push(@args, "-DWITH_NDB_TEST=1"); } + if ($opt_autotest) + { + print("compile-cluster: autotest build requested, extra everything\n"); + push(@args, "-DWITH_NDB_CCFLAGS='-DERROR_INSERT'"); + } + # The cmake generator to use if ($opt_build_type) { @@ -344,7 +375,7 @@ if (!$opt_build) push(@args, $config); } - cmd("cmake", @args); + build_cmd("cmake", @args); } else @@ -353,22 +384,335 @@ if (!$opt_build) die "You need to install cmake with version > 2.8" if ($^O eq "cygwin" or $^O eq "MSWin32"); - cmd("make"); + build_cmd("make"); } } +exit(0); + + sub cmd { my ($cmd, @a)= @_; - - if ($opt_just_print){ - print "$cmd ", join(' ', @a), "\n"; - return; - } - - print "compile-cluster: calling '$cmd ", join(' ', @a), "'\n"; + my $cmd_str = join(' ', $cmd, @a); + print "compile-cluster: '$cmd_str'\n"; + return if ($opt_just_print); system($cmd, @a) - and print("command failed: $!\n") - and exit(1); + and print("command '$cmd_str' failed\n") + and exit(1); } -exit(0); +use IPC::Open2; +sub build_cmd { + my ($cmd, @args) = @_; + my $cmd_str = join(' ', $cmd, @args); + print "compile-cluster: '$cmd_str'\n"; + return if ($opt_just_print); + $cmd_str.= " 2>&1"; + my ($chld_out, $chld_in); + my $pid = open2($chld_out, $chld_in, $cmd_str) or die $!; + # Create warning parser and pass every ouput line through it + my $parser = WarningParser->new(srcdir => $opt_srcdir, + unified => 1, + verbose => 1); + while (my $line = <$chld_out>) + { + if (!$parser->parse_line($line)) + { + # Warning parser didn't print the line, print it + print $line; + } + } + waitpid($pid, 0); + my $exit_status = $?; + my $exit_code = ($exit_status >> 8); + print "Build completed with exit_code: $exit_code(status: $exit_status)\n"; + if ($exit_code) + { + print("command '$cmd_str' failed: $!\n"); + exit(1); + } + $parser->report($0); +} + + +# Perl class used by WarningParser for keeping +# track of one individual warning +# +package WarningParser::Warning; +use strict; + +sub new { + my ($class, $file, $line, $text)= @_; + my $self= bless { + FILE => $file, + LINE => $line, + TEXT => $text, + }, $class; + return $self; +} + +sub file { + my ($self) = @_; + return $self->{FILE}; +} + +sub line { + my ($self) = @_; + return $self->{LINE}; +} + +sub text { + my ($self) = @_; + return $self->{TEXT}; +} + +# Print the warning in verbose format for easier debugging +sub print_verbose { + my ($self) = @_; + + print "{\n"; + foreach my $key (keys %$self) + { + print " $key => '$self->{$key}'\n"; + } + print "}\n"; +} + +# Print the warning in unified format(easy for automated build system to parse) +# emulate gcc +sub print_unified { + my ($self) = @_; + my $file = $self->file(); + my $line = $self->line(); + my $text = $self->text(); + print "$file:$line: warning: $text\n"; +} + +sub suppress { + my ($self, $message) = @_; + die if exists $self->{SUPPRESSED}; # Already suppressed + die unless $message; # No message + $self->{SUPPRESSED} = $message; +} + +sub is_suppressed { + my ($self) = @_; + return exists $self->{SUPPRESSED}; +} + +sub is_cluster_warning { + my ($self) = @_; + my $file = $self->{FILE}; + # Have the string ndb in the file name(including + # directory so everything below storage/ndb is + # automatically included) + if ($file =~ /ndb/) + { + return 1; + } + return 0; +} + + +package WarningParser; +use strict; +use Cwd 'abs_path'; + +sub new { + my $class= shift; + my %opts= ( @_ ); + my $srcdir = $opts{srcdir} || die "Must supply srcdir"; + my $verbose = $opts{verbose} || 0; + my $unified = $opts{unified} || 0; + my $track_dirs = $opts{track_dirs} || 0; + + my $self= bless { + # empty array of warnings + WARNINGS => [], + + # print each warning object as they are accumulated + VERBOSE => $verbose, + + # print warnings in unified format(i.e the format + # is converted to look like standard gcc). This makes it + # easy for higher level tools to parse the warnings + # regardless of compiler. + UNIFIED => $unified, + + # Need to keep track of current dir since file name in + # warnings does not include directory(this is normal + # in makefiles generated by automake) + TRACK_DIRS => $track_dirs, + + # Location of source + SRCDIR => $srcdir, + + }, $class; + return $self; +} + +sub new_warning { + my ($self, $file, $line, $text) = @_; + if ($self->{TRACK_DIRS}) + { + # file does not contain directory, add currently + # tracked dir + my $dir = $self->{DIR}; + $file= "$dir/$file"; + } + my $srcdir = $self->{SRCDIR}; + # srcdir is in abs_path form, convert also file to abs_path + $file = abs_path($file); + $file =~ s/^$srcdir//; # Remove leading srcdir + $file =~ s:^\/::; # Remove leading slash + + return WarningParser::Warning->new($file, $line, $text); +} + +sub parse_warning { + my ($self, $line) = @_; + + if ($self->{TRACK_DIRS}) + { + # Track current directory by parsing makes + # "Entering/Leaving directory" messages + if ($line =~ /Entering directory \`(.*)\'/) + { + my $dir= $1; + # Push previous dir onto stack before setting new + push(@{$self->{DIRSTACK}}, $self->{DIR}); + $self->{DIR}= $dir; + } + + if ($line =~ /Leaving directory \`(.*)\'/) + { + # Pop previous dir from stack and set it as current + my $prevdir= pop(@{$self->{DIRSTACK}}); + $self->{DIR}= $prevdir; + } + } + + # cmake and Visual Studio 10(seems to use msbuild) + if ($line =~ /^\s*(.*)\((\d+)\): warning ([^ ]*:.*)$/) + { + return $self->new_warning($1, $2, $3); + } + + # cmake and Visual Studio 9 + if ($line =~ /^(\d+>)?(?:[a-z]:)?([^:()]*)\((\d+)\) : warning ([^ ]*:.*)$/) + { + my ($project, $file, $lineno, $text) = ($1, $2, $3, $4); + return $self->new_warning($file, $lineno, $text); + } + + # cmake and gcc with line number AND column + if ($line =~ /([^ ]+\.(c|h|cc|cpp|hpp|ic|i|y|l)):([0-9]+):([0-9]+):[ \t]*warning:[ \t]*(.*)$/) + { + my ($file, $junk, $lineno, $colno, $text) = ($1, $2, $3, $4, $5); + return $self->new_warning($file, $lineno, $text); + } + + # cmake and gcc + if ($line =~ /([^ ]+\.(c|h|cc|cpp|hpp|ic|i|y|l)):[ \t]*([0-9]+):[ \t]*warning:[ \t]*(.*)$/) + { + return $self->new_warning($1, $3, $4); + } + + return undef; +} + +sub suppress_warning { + my ($self, $w) = @_; + + # Ignore files not owned by cluster team + if (!$w->is_cluster_warning()) + { + $w->suppress('Warning in file not owned by cluster team'); + return 1; + } + + # List of supressions consisting of one regex for the dir+file name + # and one for the warning text. The suppression is stored as a + # list of arrays, where each array contains two precompiled + # regexes. If both expressions match, the warning is suppressed. + my @suppressions = ( + # [ qr//, qr// ], + ); + + foreach my $sup ( @suppressions ) + { + my $file_pat = $sup->[0]; + my $text_pat = $sup->[1]; + if ($w->file() =~ /$file_pat/ and + $w->text() =~ /$text_pat/) + { + $w->suppress("Suppressed by file suppression: '$file_pat, $text_pat'"); + return 1; + } + } + + return 0; +} + +# Parse a line for warnings and return 1 if warning was +# found(even if it was suppressed) +# +sub parse_line { + my ($self, $line) = @_; + $self->{LINES}++; + + # Remove trailing line feed and new line + $line =~ s/[\r]+$//g; + $line =~ s/[\n]+$//g; + + my $w = $self->parse_warning($line); + if (defined $w) + { + if (!$self->suppress_warning($w)) + { + if ($self->{UNIFIED}) + { + # Print the warning in UNIFIED format + $w->print_unified(); + } + else + { + # Just echo the line verbatim + print "\n$line\n"; + } + } + # Print the warning object in verbose mode + $w->print_verbose() if $self->{VERBOSE}; + + # Save the warning for final report + push(@{$self->{WARNINGS}}, $w); + + return 1; + } + + return 0; +} + +sub report { + my ($self, $prefix) = @_; + my $lines = $self->{LINES}; + + my $warnings = 0; + my $suppressed= 0; + + foreach my $w (@{$self->{WARNINGS}}) + { + if ($w->is_suppressed()) + { + $suppressed++; + } + else + { + $warnings++; + } + } + my $total = $warnings + $suppressed; + print "$prefix: $warnings warnings found(suppressed $suppressed of total $total)\n"; +} + +1; === modified file 'storage/ndb/include/kernel/signaldata/LCP.hpp' --- a/storage/ndb/include/kernel/signaldata/LCP.hpp 2012-05-21 23:05:17 +0000 +++ b/storage/ndb/include/kernel/signaldata/LCP.hpp 2012-11-07 18:00:23 +0000 @@ -246,7 +246,7 @@ public: private: Uint32 senderRef; - Uint32 reqData; + Uint32 senderData; }; struct LcpStatusConf @@ -278,7 +278,7 @@ public: }; private: Uint32 senderRef; - Uint32 reqData; + Uint32 senderData; /* Backup stuff */ Uint32 lcpState; /* In lcpState == LCP_IDLE, refers to prev LCP @@ -289,11 +289,18 @@ private: Uint32 lcpDoneBytesHi; Uint32 lcpDoneBytesLo; - /* Backup stuff valid iff lcpState == LCP_SCANNING */ Uint32 tableId; Uint32 fragId; - Uint32 replicaDoneRowsHi; - Uint32 replicaDoneRowsLo; + /* Backup stuff valid iff lcpState == LCP_SCANNING or + * LCP_SCANNED + * For LCP_SCANNING contains row count of rows scanned + * (Increases as scan proceeds) + * For LCP_SCANNED contains bytes remaining to be flushed + * to file. + * (Decreases as buffer drains to file) + */ + Uint32 completionStateHi; + Uint32 completionStateLo; }; struct LcpStatusRef @@ -325,7 +332,7 @@ public: private: Uint32 senderRef; - Uint32 reqData; + Uint32 senderData; Uint32 error; }; === modified file 'storage/ndb/include/mgmapi/mgmapi.h' --- a/storage/ndb/include/mgmapi/mgmapi.h 2011-09-29 09:23:04 +0000 +++ b/storage/ndb/include/mgmapi/mgmapi.h 2012-11-07 13:42:55 +0000 @@ -402,7 +402,11 @@ extern "C" { void ndb_mgm_destroy_handle(NdbMgmHandle * handle); /** - * Set a name of the handle. Name is reported in cluster log. + * Set a name of the handle. + * + * NOTE! Name is reported in cluster log only when the + * handle subsequently is used to allocate a nodeid + * using ndb_mgm_alloc_nodeid(). * * @param handle Management handle * @param name Name === modified file 'storage/ndb/memcache/include/int3korr.h' --- a/storage/ndb/memcache/include/int3korr.h 2011-11-07 18:47:48 +0000 +++ b/storage/ndb/memcache/include/int3korr.h 2012-11-12 13:53:54 +0000 @@ -30,4 +30,4 @@ #define uint3korr(A) (Uint32) (((Uint32) ((Uint8) (A)[0])) +\ (((Uint32) ((Uint8) (A)[1])) << 8) +\ (((Uint32) ((Uint8) (A)[2])) << 16)) - \ No newline at end of file + === modified file 'storage/ndb/src/common/debugger/signaldata/LCP.cpp' --- a/storage/ndb/src/common/debugger/signaldata/LCP.cpp 2012-05-21 22:27:28 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/LCP.cpp 2012-11-07 17:29:01 +0000 @@ -95,8 +95,8 @@ printLCP_STATUS_REQ(FILE * output, const Uint32 len, Uint16 receiverBlockNo){ const LcpStatusReq* const sig = (LcpStatusReq*) theData; - fprintf(output, " SenderRef : %x ReqData : %u\n", - sig->senderRef, sig->reqData); + fprintf(output, " SenderRef : %x SenderData : %u\n", + sig->senderRef, sig->senderData); return true; } @@ -105,10 +105,10 @@ printLCP_STATUS_CONF(FILE * output, cons Uint32 len, Uint16 receiverBlockNo){ const LcpStatusConf* const sig = (LcpStatusConf*) theData; - fprintf(output, " SenderRef : %x ReqData : %u LcpState : %u tableId : %u fragId : %u\n", - sig->senderRef, sig->reqData, sig->lcpState, sig->tableId, sig->fragId); - fprintf(output, " replica(DoneRows : %llu), lcpDone (Rows : %llu, Bytes : %llu)\n", - (((Uint64)sig->replicaDoneRowsHi) << 32) + sig->replicaDoneRowsLo, + fprintf(output, " SenderRef : %x SenderData : %u LcpState : %u tableId : %u fragId : %u\n", + sig->senderRef, sig->senderData, sig->lcpState, sig->tableId, sig->fragId); + fprintf(output, " replica(Progress : %llu), lcpDone (Rows : %llu, Bytes : %llu)\n", + (((Uint64)sig->completionStateHi) << 32) + sig->completionStateLo, (((Uint64)sig->lcpDoneRowsHi) << 32) + sig->lcpDoneRowsLo, (((Uint64)sig->lcpDoneBytesHi) << 32) + sig->lcpDoneBytesLo); return true; @@ -119,7 +119,7 @@ printLCP_STATUS_REF(FILE * output, const Uint32 len, Uint16 receiverBlockNo){ const LcpStatusRef* const sig = (LcpStatusRef*) theData; - fprintf(output, " SenderRef : %x, ReqData : %u Error : %u\n", - sig->senderRef, sig->reqData, sig->error); + fprintf(output, " SenderRef : %x, SenderData : %u Error : %u\n", + sig->senderRef, sig->senderData, sig->error); return true; } === modified file 'storage/ndb/src/kernel/blocks/backup/Backup.cpp' --- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2012-09-13 20:47:06 +0000 +++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp 2012-11-09 14:37:51 +0000 @@ -4792,6 +4792,13 @@ Backup::ready_to_write(bool ready, Uint3 ndbout << endl << "Current Millisecond is = "; ndbout << NdbTick_CurrentMillisecond() << endl; #endif + + if (ERROR_INSERTED(10043) && eof) + { + /* Block indefinitely without closing the file */ + return false; + } + if ((ready || eof) && m_words_written_this_period <= m_curr_disk_write_speed) { @@ -5966,7 +5973,7 @@ Backup::execLCP_STATUS_REQ(Signal* signa const LcpStatusReq* req = (const LcpStatusReq*) signal->getDataPtr(); const Uint32 senderRef = req->senderRef; - const Uint32 reqData = req->reqData; + const Uint32 senderData = req->senderData; Uint32 failCode = LcpStatusRef::NoLCPRecord; /* Find LCP backup, if there is one */ @@ -5985,18 +5992,23 @@ Backup::execLCP_STATUS_REQ(Signal* signa switch (ptr.p->slaveState.getState()) { case STARTED: + jam(); state = LcpStatusConf::LCP_PREPARED; break; case SCANNING: + jam(); state = LcpStatusConf::LCP_SCANNING; break; case STOPPING: + jam(); state = LcpStatusConf::LCP_SCANNED; break; case DEFINED: + jam(); state = LcpStatusConf::LCP_IDLE; break; default: + jam(); ndbout_c("Unusual LCP state in LCP_STATUS_REQ() : %u", ptr.p->slaveState.getState()); state = LcpStatusConf::LCP_IDLE; @@ -6007,12 +6019,12 @@ Backup::execLCP_STATUS_REQ(Signal* signa LcpStatusConf* conf = (LcpStatusConf*) signal->getDataPtr(); conf->senderRef = reference(); - conf->reqData = reqData; + conf->senderData = senderData; conf->lcpState = state; conf->tableId = UnsetConst; conf->fragId = UnsetConst; - conf->replicaDoneRowsHi = UnsetConst; - conf->replicaDoneRowsLo = UnsetConst; + conf->completionStateHi = UnsetConst; + conf->completionStateLo = UnsetConst; setWords(ptr.p->noOfRecords, conf->lcpDoneRowsHi, conf->lcpDoneRowsLo); @@ -6020,22 +6032,15 @@ Backup::execLCP_STATUS_REQ(Signal* signa conf->lcpDoneBytesHi, conf->lcpDoneBytesLo); - if (state == LcpStatusConf::LCP_SCANNING) + if (state == LcpStatusConf::LCP_SCANNING || + state == LcpStatusConf::LCP_SCANNED) { - /* Actually scanning a fragment, let's grab the details */ + jam(); + /* Actually scanning/closing a fragment, let's grab the details */ TablePtr tabPtr; FragmentPtr fragPtr; BackupFilePtr filePtr; - ptr.p->tables.first(tabPtr); - if (tabPtr.i == RNIL) - { - jam(); - failCode = LcpStatusRef::NoTableRecord; - break; - } - tabPtr.p->fragments.getPtr(fragPtr, 0); - ndbrequire(fragPtr.p->tableId == tabPtr.p->tableId); if (ptr.p->dataFilePtr == RNIL) { jam(); @@ -6044,11 +6049,40 @@ Backup::execLCP_STATUS_REQ(Signal* signa } c_backupFilePool.getPtr(filePtr, ptr.p->dataFilePtr); ndbrequire(filePtr.p->backupPtr == ptr.i); - conf->tableId = tabPtr.p->tableId; - conf->fragId = fragPtr.p->fragmentId; - setWords(filePtr.p->operation.noOfRecords, - conf->replicaDoneRowsHi, - conf->replicaDoneRowsLo); + + ptr.p->tables.first(tabPtr); + if (tabPtr.i != RNIL) + { + jam(); + tabPtr.p->fragments.getPtr(fragPtr, 0); + ndbrequire(fragPtr.p->tableId == tabPtr.p->tableId); + conf->tableId = tabPtr.p->tableId; + conf->fragId = fragPtr.p->fragmentId; + } + + if (state == LcpStatusConf::LCP_SCANNING) + { + jam(); + setWords(filePtr.p->operation.noOfRecords, + conf->completionStateHi, + conf->completionStateLo); + } + else if (state == LcpStatusConf::LCP_SCANNED) + { + jam(); + /* May take some time to drain the FS buffer, depending on + * size of buff, achieved rate. + * We provide the buffer fill level so that requestors + * can observe whether there's progress in this phase. + */ + Uint64 flushBacklog = + filePtr.p->operation.dataBuffer.getUsableSize() - + filePtr.p->operation.dataBuffer.getFreeSize(); + + setWords(flushBacklog, + conf->completionStateHi, + conf->completionStateLo); + } } failCode = 0; @@ -6067,7 +6101,7 @@ Backup::execLCP_STATUS_REQ(Signal* signa LcpStatusRef* ref = (LcpStatusRef*) signal->getDataPtr(); ref->senderRef = reference(); - ref->reqData = reqData; + ref->senderData = senderData; ref->error = failCode; sendSignal(senderRef, GSN_LCP_STATUS_REF, === modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp' --- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2012-10-17 14:43:50 +0000 +++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2012-11-07 18:00:23 +0000 @@ -1095,6 +1095,8 @@ public: STATIC_CONST( PollingPeriodMillis = 10000 ); /* 10s */ STATIC_CONST( WarnPeriodsWithNoProgress = 2); /* 20s */ STATIC_CONST( MaxPeriodsWithNoProgress = 6 ); /* 60s */ + + SimulatedBlock* block; /* Should the watchdog be running? */ bool scan_running; @@ -1102,45 +1104,23 @@ public: /* Is there an active thread? */ bool thread_active; - /* LCP position info from Backup block */ + /* LCP position and state info from Backup block */ + LcpStatusConf::LcpState lcpState; Uint32 tableId; Uint32 fragId; - Uint64 rowCount; + Uint64 completionStatus; /* Number of periods with no LCP progress observed */ Uint32 pollCount; /* Reinitialise the watchdog */ - void reset() - { - scan_running = false; - tableId = ~Uint32(0); - fragId = ~Uint32(0); - rowCount = ~Uint64(0); - pollCount = 0; - } + void reset(); /* Handle an LCP Status report */ - void handleLcpStatusRep(Uint32 repTableId, + void handleLcpStatusRep(LcpStatusConf::LcpState repLcpState, + Uint32 repTableId, Uint32 repFragId, - Uint64 repRowCount) - { - if (scan_running) - { - if ((repRowCount != rowCount) || - (repFragId != fragId) || - (repTableId != tableId)) - { - /* Something moved since last time, reset - * poll counter and data. - */ - pollCount = 0; - tableId = repTableId; - fragId = repFragId; - rowCount = repRowCount; - } - } - } + Uint64 repCompletionStatus); }; LCPFragWatchdog c_lcpFragWatchdog; === modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp' --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp 2012-08-13 14:03:42 +0000 +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp 2012-11-07 18:00:23 +0000 @@ -96,6 +96,7 @@ void Dblqh::initData() c_max_parallel_scans_per_frag = 32; + c_lcpFragWatchdog.block = this; c_lcpFragWatchdog.reset(); c_lcpFragWatchdog.thread_active = false; }//Dblqh::initData() === modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp' --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-11-06 08:01:13 +0000 +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-11-07 18:07:24 +0000 @@ -23649,7 +23649,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal /* Send LCP_STATUS_REQ to BACKUP */ LcpStatusReq* req = (LcpStatusReq*) signal->getDataPtr(); req->senderRef = reference(); - req->reqData = 0; + req->senderData = 0; BlockReference backupRef = calcInstanceBlockRef(BACKUP); sendSignal(backupRef, GSN_LCP_STATUS_REQ, signal, @@ -23996,7 +23996,7 @@ Dblqh::invokeLcpFragWatchdogThread(Signa LcpStatusReq* req = (LcpStatusReq*)signal->getDataPtr(); req->senderRef = cownref; - req->reqData = 1; + req->senderData = 1; BlockReference backupRef = calcInstanceBlockRef(BACKUP); sendSignal(backupRef, GSN_LCP_STATUS_REQ, signal, LcpStatusReq::SignalLength, JBB); @@ -24008,7 +24008,7 @@ Dblqh::execLCP_STATUS_CONF(Signal* signa jamEntry(); LcpStatusConf* conf = (LcpStatusConf*) signal->getDataPtr(); - if (conf->reqData == 0) + if (conf->senderData == 0) { /* DUMP STATE variant */ ndbout_c("Received LCP_STATUS_CONF from %x", conf->senderRef); @@ -24016,8 +24016,8 @@ Dblqh::execLCP_STATUS_CONF(Signal* signa conf->lcpState, conf->tableId, conf->fragId); - ndbout_c(" Replica done rows %llu", - (((Uint64)conf->replicaDoneRowsHi) << 32) + conf->replicaDoneRowsLo); + ndbout_c(" Completion State %llu", + (((Uint64)conf->completionStateHi) << 32) + conf->completionStateLo); ndbout_c(" Lcp done rows %llu, done bytes %llu", (((Uint64)conf->lcpDoneRowsHi) << 32) + conf->lcpDoneRowsLo, (((Uint64)conf->lcpDoneBytesHi) << 32) + conf->lcpDoneBytesLo); @@ -24026,10 +24026,11 @@ Dblqh::execLCP_STATUS_CONF(Signal* signa /* We can ignore the LCP status as if it's complete then we should * promptly stop watching */ - c_lcpFragWatchdog.handleLcpStatusRep(conf->tableId, + c_lcpFragWatchdog.handleLcpStatusRep((LcpStatusConf::LcpState)conf->lcpState, + conf->tableId, conf->fragId, - (((Uint64)conf->replicaDoneRowsHi) << 32) + - conf->replicaDoneRowsLo); + (((Uint64)conf->completionStateHi) << 32) + + conf->completionStateLo); } void @@ -24038,12 +24039,53 @@ Dblqh::execLCP_STATUS_REF(Signal* signal jamEntry(); LcpStatusRef* ref = (LcpStatusRef*) signal->getDataPtr(); - ndbout_c("Received LCP_STATUS_REF from %x, reqData = %u with error code %u", - ref->senderRef, ref->reqData, ref->error); + ndbout_c("Received LCP_STATUS_REF from %x, senderData = %u with error code %u", + ref->senderRef, ref->senderData, ref->error); ndbrequire(false); } +void +Dblqh::LCPFragWatchdog::reset() +{ + jamBlock(block); + scan_running = false; + lcpState = LcpStatusConf::LCP_IDLE; + tableId = ~Uint32(0); + fragId = ~Uint32(0); + completionStatus = ~Uint64(0); + pollCount = 0; +} + +void +Dblqh::LCPFragWatchdog::handleLcpStatusRep(LcpStatusConf::LcpState repLcpState, + Uint32 repTableId, + Uint32 repFragId, + Uint64 repCompletionStatus) +{ + jamBlock(block); + if (scan_running) + { + jamBlock(block); + if ((repCompletionStatus != completionStatus) || + (repFragId != fragId) || + (repTableId != tableId) || + (repLcpState != lcpState)) + { + jamBlock(block); + /* Something moved since last time, reset + * poll counter and data. + */ + pollCount = 0; + lcpState = repLcpState; + tableId = repTableId; + fragId = repFragId; + completionStatus = repCompletionStatus; + } + } +} + + /** * checkLcpFragWatchdog * @@ -24071,20 +24113,27 @@ Dblqh::checkLcpFragWatchdog(Signal* sign LCPFragWatchdog::WarnPeriodsWithNoProgress) { jam(); + const char* completionStatusString = + (c_lcpFragWatchdog.lcpState == LcpStatusConf::LCP_SCANNING? + "rows completed": + "bytes remaining."); + warningEvent("LCP Frag watchdog : No progress on table %u, frag %u for %u s." - " %llu rows completed", + " %llu %s", c_lcpFragWatchdog.tableId, c_lcpFragWatchdog.fragId, (LCPFragWatchdog::PollingPeriodMillis * c_lcpFragWatchdog.pollCount) / 1000, - c_lcpFragWatchdog.rowCount); + c_lcpFragWatchdog.completionStatus, + completionStatusString); ndbout_c("LCP Frag watchdog : No progress on table %u, frag %u for %u s." - " %llu rows completed", + " %llu %s", c_lcpFragWatchdog.tableId, c_lcpFragWatchdog.fragId, (LCPFragWatchdog::PollingPeriodMillis * c_lcpFragWatchdog.pollCount) / 1000, - c_lcpFragWatchdog.rowCount); + c_lcpFragWatchdog.completionStatus, + completionStatusString); if (c_lcpFragWatchdog.pollCount >= LCPFragWatchdog::MaxPeriodsWithNoProgress) === modified file 'storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp' --- a/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2012-09-19 07:09:57 +0000 +++ b/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2012-11-08 12:02:48 +0000 @@ -152,6 +152,12 @@ public: }; typedef Ptr TableRecordPtr; + enum Buffer_type { + BUFFER_VOID = 0, + BUFFER_STACK = 1, + BUFFER_VAR = 2 + }; + struct RowRef { Uint32 m_page_id; @@ -159,7 +165,7 @@ public: union { Uint16 unused; - Uint16 m_allocator; + enum Buffer_type m_alloc_type:16; }; void copyto_link(Uint32 * dst) const { @@ -198,7 +204,6 @@ public: struct RowPtr { Uint32 m_type; - Uint32 m_src_node_no; Uint32 m_src_node_ptrI; Uint32 m_src_correlation; @@ -234,8 +239,26 @@ public: }; }; - struct SLFifoRowList + struct RowBuffer; // forward decl. + + /** + * Define overlayed 'base class' for SLFifoRowList and RowMap. + * As we want these to be POD struct, we does not use + * inheritance, but have to take care that first part + * of these struct are correctly overlayed. + */ + struct RowCollectionBase { + RowBuffer* m_rowBuffer; + }; + + struct SLFifoRowList //: public RowCollectionBase + { + /** + * BEWARE: Overlayed 'struct RowCollectionBase' + */ + RowBuffer* m_rowBuffer; + /** * Data used for a single linked list of rows */ @@ -244,13 +267,22 @@ public: Uint16 m_first_row_page_pos; Uint16 m_last_row_page_pos; + void construct(RowBuffer& rowBuffer) { + m_rowBuffer = &rowBuffer; + init(); + } void init() { m_first_row_page_id = RNIL;} bool isNull() const { return m_first_row_page_id == RNIL; } }; - struct RowMap + struct RowMap //: public RowCollectionBase { /** + * BEWARE: Overlayed 'struct RowCollectionBase' + */ + RowBuffer* m_rowBuffer; + + /** * Data used for a map with rows (key is correlation id) * currently a single array is used to store row references * (size == batch size) @@ -259,7 +291,18 @@ public: Uint16 m_size; // size of array Uint16 m_elements; // #elements in array - void init() { m_map_ref.setNull();} + void construct(RowBuffer& rowBuffer, + Uint32 capacity) + { + m_rowBuffer = &rowBuffer; + m_size = capacity; + init(); + } + void init() { + m_map_ref.setNull(); + m_elements = 0; + } + bool isNull() const { return m_map_ref.isNull(); } void assign (RowRef ref) { @@ -296,7 +339,14 @@ public: STATIC_CONST( MAP_SIZE_PER_REF_16 = 3 ); }; - struct SLFifoRowListIterator + /** + * Define overlayed 'base class' for SLFifoRowListIterator + * and RowMapIterator. + * As we want these to be POD struct, we does not use + * inheritance, but have to take care that first part + * of these struct are correctly overlayed. + */ + struct RowIteratorBase { RowRef m_ref; Uint32 * m_row_ptr; @@ -305,27 +355,96 @@ public: void setNull() { m_ref.setNull(); } }; - struct SLFifoRowListIteratorPtr + struct SLFifoRowListIterator //: public RowIteratorBase { + /** + * BEWARE: Overlayed 'struct RowIteratorBase' + */ RowRef m_ref; + Uint32 * m_row_ptr; + + bool isNull() const { return m_ref.isNull(); } + void setNull() { m_ref.setNull(); } + // END: RowIteratorBase }; - struct RowMapIterator + struct RowMapIterator //: public RowIteratorBase { + /** + * BEWARE: Overlayed 'struct RowIteratorBase' + */ + RowRef m_ref; Uint32 * m_row_ptr; + + bool isNull() const { return m_ref.isNull(); } + void setNull() { m_ref.setNull(); } + // END: RowIteratorBase + Uint32 * m_map_ptr; - RowRef m_ref; // position of actual row Uint16 m_size; Uint16 m_element_no; - bool isNull() const { return m_ref.isNull(); } - void setNull() { m_ref.setNull(); } }; - struct RowMapIteratorPtr + /** + * Abstraction of SLFifoRowList & RowMap + */ + struct RowCollection { - Uint32 m_element_no; + enum collection_type + { + COLLECTION_VOID, + COLLECTION_MAP, + COLLECTION_LIST + }; + union + { + RowCollectionBase m_base; // Common part for map & list + SLFifoRowList m_list; + RowMap m_map; + }; + + RowCollection() : m_type(COLLECTION_VOID) {} + + void construct(collection_type type, + RowBuffer& rowBuffer, + Uint32 capacity) + { + m_type = type; + if (m_type == COLLECTION_MAP) + m_map.construct(rowBuffer,capacity); + else if (m_type == COLLECTION_LIST) + m_list.construct(rowBuffer); + } + + void init() { + if (m_type == COLLECTION_MAP) + m_map.init(); + else if (m_type == COLLECTION_LIST) + m_list.init(); + } + + Uint32 rowOffset() const { + return (m_type == COLLECTION_MAP) ? 0 : 2; + } + + collection_type m_type; }; + struct RowIterator + { + union + { + RowIteratorBase m_base; // Common part for map & list + SLFifoRowListIterator m_list; + RowMapIterator m_map; + }; + RowCollection::collection_type m_type; + + RowIterator() { init(); } + void init() { m_base.setNull(); } + bool isNull() const { return m_base.isNull(); } + }; + /** * A struct used when building an TreeNode @@ -368,11 +487,24 @@ public: struct RowBuffer { - RowBuffer() { stack_init(); } + enum Buffer_type m_type; + + RowBuffer() : m_type(BUFFER_VOID) {} DLFifoList::Head m_page_list; - void stack_init() { new (&m_page_list) DLFifoList::Head(); m_stack.m_pos = 0xFFFF; } - void var_init() { new (&m_page_list) DLFifoList::Head(); m_var.m_free = 0; } + void init(enum Buffer_type type) + { + new (&m_page_list) DLFifoList::Head(); + m_type = type; + reset(); + } + void reset() + { + if (m_type == BUFFER_STACK) + m_stack.m_pos = 0xFFFF; + else if (m_type == BUFFER_VAR) + m_var.m_free = 0; + } struct Stack { @@ -840,11 +972,7 @@ public: /** * Rows buffered by this node */ - union - { - RowMap m_row_map; - SLFifoRowList m_row_list; - }; + RowCollection m_rows; union { @@ -892,7 +1020,7 @@ public: RT_SCAN = 0x1 // unbounded result set, scan interface ,RT_ROW_BUFFERS = 0x2 // Do any of the node use row-buffering ,RT_MULTI_SCAN = 0x4 // Is there several scans in request - ,RT_VAR_ALLOC = 0x8 // Is var-allocation used for row-buffer +// ,RT_VAR_ALLOC = 0x8 // DEPRECATED ,RT_NEED_PREPARE = 0x10 // Does any node need m_prepare hook ,RT_NEED_COMPLETE = 0x20 // Does any node need m_complete hook ,RT_REPEAT_SCAN_RESULT = 0x40 // Repeat bushy scan result when required @@ -1122,6 +1250,7 @@ private: */ const OpInfo* getOpInfo(Uint32 op); Uint32 build(Build_context&,Ptr,SectionReader&,SectionReader&); + Uint32 initRowBuffers(Ptr); void checkPrepareComplete(Signal*, Ptr, Uint32 cnt); void start(Signal*, Ptr); void checkBatchComplete(Signal*, Ptr, Uint32 cnt); @@ -1138,7 +1267,6 @@ private: void releaseScanBuffers(Ptr requestPtr); void releaseRequestBuffers(Ptr requestPtr, bool reset); void releaseNodeRows(Ptr requestPtr, Ptr); - void releaseRow(Ptr, RowRef ref); void registerActiveCursor(Ptr, Ptr); void nodeFail_checkRequests(Signal*); void cleanup_common(Ptr, Ptr); @@ -1146,31 +1274,37 @@ private: /** * Row buffering */ - Uint32 storeRow(Ptr, Ptr, RowPtr &row); + Uint32 storeRow(RowCollection& collection, RowPtr &row); + void releaseRow(RowCollection& collection, RowRef ref); Uint32* stackAlloc(RowBuffer& dst, RowRef&, Uint32 len); Uint32* varAlloc(RowBuffer& dst, RowRef&, Uint32 len); + Uint32* rowAlloc(RowBuffer& dst, RowRef&, Uint32 len); - void add_to_list(SLFifoRowList & list, RowRef rowref); - Uint32 add_to_map(Ptr requestPtr, Ptr, Uint32, RowRef); - Uint32 * get_row_ptr(const RowMap&, RowMapIterator pos); - void setupRowPtr(Ptr, RowPtr& dst, RowRef, const Uint32 * src); - - // NOTE: ref contains info about it being stack/var - // so adding an inline would be nice...but that remove possibility - // to add jam()'s - Uint32 * get_row_ptr_stack(RowRef pos); - Uint32 * get_row_ptr_var(RowRef pos); + void add_to_list(SLFifoRowList & list, RowRef); + Uint32 add_to_map(RowMap& map, Uint32, RowRef); + + void setupRowPtr(const RowCollection& collection, + RowPtr& dst, RowRef, const Uint32 * src); + Uint32 * get_row_ptr(RowRef pos); /** * SLFifoRowListIterator */ - bool first(Ptr, Ptr, SLFifoRowListIterator&); + bool first(const SLFifoRowList& list, SLFifoRowListIterator&); bool next(SLFifoRowListIterator&); - bool next(Ptr, Ptr, SLFifoRowListIterator&, SLFifoRowListIteratorPtr); - bool first(Ptr, Ptr, RowMapIterator&); + /** + * RowMapIterator + */ + bool first(const RowMap& map, RowMapIterator&); bool next(RowMapIterator&); - bool next(Ptr,Ptr, RowMapIterator&, RowMapIteratorPtr); + + /** + * RowIterator: + * Abstraction which may iterate either a RowList or Map + */ + bool first(const RowCollection&, RowIterator&); + bool next(RowIterator&); /** * Misc === modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2012-10-05 07:45:53 +0000 +++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2012-11-08 12:02:48 +0000 @@ -44,34 +44,31 @@ #include #include -// Use DEBUG to print messages that should be -// seen only when we debug the product - #ifdef VM_TRACE +/** + * DEBUG options for different parts od SPJ block + * Comment out those part you don't want DEBUG'ed. + */ #define DEBUG(x) ndbout << "DBSPJ: "<< x << endl; -#define DEBUG_DICT(x) ndbout << "DBSPJ: "<< x << endl; -#define DEBUG_LQHKEYREQ -#define DEBUG_SCAN_FRAGREQ - -#else +//#define DEBUG_DICT(x) ndbout << "DBSPJ: "<< x << endl; +//#define DEBUG_LQHKEYREQ +//#define DEBUG_SCAN_FRAGREQ +#endif +/** + * Provide empty defs for those DEBUGs which has to be defined. + */ +#if !defined(DEBUG) #define DEBUG(x) -#define DEBUG_DICT(x) - #endif -#define DEBUG_CRASH() ndbassert(false) - -#if 1 -#undef DEBUG -#define DEBUG(x) -#undef DEBUG_DICT +#if !defined(DEBUG_DICT) #define DEBUG_DICT(x) -#undef DEBUG_LQHKEYREQ -#undef DEBUG_SCAN_FRAGREQ #endif +#define DEBUG_CRASH() ndbassert(false) + const Ptr Dbspj::NullTreeNodePtr = { 0, RNIL }; const Dbspj::RowRef Dbspj::NullRowRef = { RNIL, GLOBAL_PAGE_SIZE_WORDS, { 0 } }; @@ -1289,54 +1286,92 @@ Dbspj::build(Build_context& ctx, } requestPtr.p->m_node_cnt = ctx.m_cnt; + if (ctx.m_scan_cnt > 1) + { + jam(); + requestPtr.p->m_bits |= Request::RT_MULTI_SCAN; + } + + // Construct RowBuffers where required + err = initRowBuffers(requestPtr); + if (unlikely(err != 0)) + { + jam(); + goto error; + } + + return 0; + +error: + jam(); + return err; +} + +/** + * initRowBuffers will decide row-buffering strategy, and init + * the RowBuffers where required. + */ +Uint32 +Dbspj::initRowBuffers(Ptr requestPtr) +{ + Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes); + /** - * Init ROW_BUFFERS for those TreeNodes requiring either - * T_ROW_BUFFER or T_ROW_BUFFER_MAP. + * Init ROW_BUFFERS iff Request has to buffer any rows. */ if (requestPtr.p->m_bits & Request::RT_ROW_BUFFERS) { + jam(); + + /** + * Iff, multi-scan is non-bushy (normal case) + * we don't strictly need BUFFER_VAR for RT_ROW_BUFFERS + * but could instead pop-row stack frame, + * however this is not implemented... + * + * so, currently use BUFFER_VAR if 'RT_MULTI_SCAN' + * + * NOTE: This should easily be solvable by having a + * RowBuffer for each TreeNode instead + */ + if (requestPtr.p->m_bits & Request::RT_MULTI_SCAN) + { + jam(); + requestPtr.p->m_rowBuffer.init(BUFFER_VAR); + } + else + { + jam(); + requestPtr.p->m_rowBuffer.init(BUFFER_STACK); + } + Ptr treeNodePtr; - Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes); for (list.first(treeNodePtr); !treeNodePtr.isNull(); list.next(treeNodePtr)) { + jam(); + ndbassert(treeNodePtr.p->m_batch_size > 0); + /** + * Construct a List or Map RowCollection for those TreeNodes + * requiring rows to be buffered. + */ if (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP) { jam(); - treeNodePtr.p->m_row_map.init(); + treeNodePtr.p->m_rows.construct (RowCollection::COLLECTION_MAP, + requestPtr.p->m_rowBuffer, + treeNodePtr.p->m_batch_size); } else if (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER) { jam(); - treeNodePtr.p->m_row_list.init(); + treeNodePtr.p->m_rows.construct (RowCollection::COLLECTION_LIST, + requestPtr.p->m_rowBuffer, + treeNodePtr.p->m_batch_size); } } } - if (ctx.m_scan_cnt > 1) - { - jam(); - requestPtr.p->m_bits |= Request::RT_MULTI_SCAN; - - /** - * Iff, multi-scan is non-bushy (normal case) - * we don't strictly need RT_VAR_ALLOC for RT_ROW_BUFFERS - * but could instead pop-row stack frame, - * however this is not implemented... - * - * so, use RT_VAR_ALLOC - */ - if (requestPtr.p->m_bits & Request::RT_ROW_BUFFERS) - { - jam(); - requestPtr.p->m_bits |= Request::RT_VAR_ALLOC; - } - } - return 0; - -error: - jam(); - return err; } Uint32 @@ -1859,64 +1894,46 @@ Dbspj::releaseNodeRows(Ptr requ << ", request: " << requestPtr.i ); - // only when var-alloc, or else stack will be popped wo/ consideration - // to individual rows - ndbassert(requestPtr.p->m_bits & Request::RT_VAR_ALLOC); ndbassert(treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER); - /** - * Two ways to iterate... - */ - if ((treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP) == 0) + Uint32 cnt = 0; + RowIterator iter; + for (first(treeNodePtr.p->m_rows, iter); !iter.isNull(); ) { jam(); - Uint32 cnt = 0; - SLFifoRowListIterator iter; - for (first(requestPtr, treeNodePtr, iter); !iter.isNull(); ) - { - jam(); - RowRef pos = iter.m_ref; - next(iter); - releaseRow(requestPtr, pos); - cnt ++; - } - treeNodePtr.p->m_row_list.init(); - DEBUG("SLFifoRowListIterator: released " << cnt << " rows!"); + RowRef pos = iter.m_base.m_ref; + next(iter); + releaseRow(treeNodePtr.p->m_rows, pos); + cnt ++; } - else + treeNodePtr.p->m_rows.init(); + DEBUG("RowIterator: released " << cnt << " rows!"); + + if (treeNodePtr.p->m_rows.m_type == RowCollection::COLLECTION_MAP) { jam(); - Uint32 cnt = 0; - RowMapIterator iter; - for (first(requestPtr, treeNodePtr, iter); !iter.isNull(); ) - { - jam(); - RowRef pos = iter.m_ref; - // this could be made more efficient by not actually seting up m_row_ptr - next(iter); - releaseRow(requestPtr, pos); - cnt++; - } - // Release the (now empty) RowMap - RowMap& map = treeNodePtr.p->m_row_map; + RowMap& map = treeNodePtr.p->m_rows.m_map; if (!map.isNull()) { jam(); RowRef ref; map.copyto(ref); - releaseRow(requestPtr, ref); // Map was allocated in row memory - map.init(); + releaseRow(treeNodePtr.p->m_rows, ref); // Map was allocated in row memory } - DEBUG("RowMapIterator: released " << cnt << " rows!"); } } void -Dbspj::releaseRow(Ptr requestPtr, RowRef pos) +Dbspj::releaseRow(RowCollection& collection, RowRef pos) { - ndbassert(requestPtr.p->m_bits & Request::RT_VAR_ALLOC); - ndbassert(pos.m_allocator == 1); + // only when var-alloc, or else stack will be popped wo/ consideration + // to individual rows + ndbassert(collection.m_base.m_rowBuffer != NULL); + ndbassert(collection.m_base.m_rowBuffer->m_type == BUFFER_VAR); + ndbassert(pos.m_alloc_type == BUFFER_VAR); + + RowBuffer& rowBuffer = *collection.m_base.m_rowBuffer; Ptr ptr; m_page_pool.getPtr(ptr, pos.m_page_id); ((Var_page*)ptr.p)->free_record(pos.m_page_pos, Var_page::CHAIN); @@ -1925,7 +1942,7 @@ Dbspj::releaseRow(Ptr requestPt { jam(); LocalDLFifoList list(m_page_pool, - requestPtr.p->m_rowBuffer.m_page_list); + rowBuffer.m_page_list); const bool last = list.hasNext(ptr) == false; list.remove(ptr); if (list.isEmpty()) @@ -1935,7 +1952,7 @@ Dbspj::releaseRow(Ptr requestPt * Don't remove last page... */ list.addLast(ptr); - requestPtr.p->m_rowBuffer.m_var.m_free = free_space; + rowBuffer.m_var.m_free = free_space; } else { @@ -1948,20 +1965,19 @@ Dbspj::releaseRow(Ptr requestPt */ Ptr newLastPtr; ndbrequire(list.last(newLastPtr)); - requestPtr.p->m_rowBuffer.m_var.m_free = - ((Var_page*)newLastPtr.p)->free_space; + rowBuffer.m_var.m_free = ((Var_page*)newLastPtr.p)->free_space; } releasePage(ptr); } } - else if (free_space > requestPtr.p->m_rowBuffer.m_var.m_free) + else if (free_space > rowBuffer.m_var.m_free) { jam(); LocalDLFifoList list(m_page_pool, - requestPtr.p->m_rowBuffer.m_page_list); + rowBuffer.m_page_list); list.remove(ptr); list.addLast(ptr); - requestPtr.p->m_rowBuffer.m_var.m_free = free_space; + rowBuffer.m_var.m_free = free_space; } } @@ -1988,7 +2004,7 @@ Dbspj::releaseRequestBuffers(Ptrm_rowBuffer.stack_init(); + requestPtr.p->m_rowBuffer.reset(); } if (reset) @@ -1998,19 +2014,7 @@ Dbspj::releaseRequestBuffers(Ptrm_bits & TreeNode::T_ROW_BUFFER) - { - jam(); - if (nodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP) - { - jam(); - nodePtr.p->m_row_map.init(); - } - else - { - nodePtr.p->m_row_list.init(); - } - } + nodePtr.p->m_rows.init(); } } } @@ -2569,6 +2573,11 @@ Dbspj::execTRANSID_AI(Signal* signal) { jam(); Uint32 err; + + DEBUG("Need to storeRow" + << ", node: " << treeNodePtr.p->m_node_no + ); + if (ERROR_INSERTED(17120) || (ERROR_INSERTED(17121) && treeNodePtr.p->m_parentPtrI != RNIL)) { @@ -2576,7 +2585,7 @@ Dbspj::execTRANSID_AI(Signal* signal) CLEAR_ERROR_INSERT_VALUE; abort(signal, requestPtr, DbspjErr::OutOfRowMemory); } - else if ((err = storeRow(requestPtr, treeNodePtr, row)) != 0) + else if ((err = storeRow(treeNodePtr.p->m_rows, row)) != 0) { jam(); abort(signal, requestPtr, err); @@ -2593,60 +2602,43 @@ Dbspj::execTRANSID_AI(Signal* signal) } Uint32 -Dbspj::storeRow(Ptr requestPtr, Ptr treeNodePtr, RowPtr &row) +Dbspj::storeRow(RowCollection& collection, RowPtr &row) { ndbassert(row.m_type == RowPtr::RT_SECTION); SegmentedSectionPtr dataPtr = row.m_row_data.m_section.m_dataPtr; Uint32 * headptr = (Uint32*)row.m_row_data.m_section.m_header; Uint32 headlen = 1 + row.m_row_data.m_section.m_header->m_len; - DEBUG("storeRow" - << ", node: " << treeNodePtr.p->m_node_no - << ", request: " << requestPtr.i - ); - /** - * If rows are not in map, then they are kept in linked list + * Rows might be stored at an offset within the collection. */ - Uint32 linklen = (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP)? - 0 : 2; + const Uint32 offset = collection.rowOffset(); Uint32 totlen = 0; totlen += dataPtr.sz; totlen += headlen; - totlen += linklen; + totlen += offset; RowRef ref; - Uint32 * dstptr = 0; - if ((requestPtr.p->m_bits & Request::RT_VAR_ALLOC) == 0) - { - jam(); - dstptr = stackAlloc(requestPtr.p->m_rowBuffer, ref, totlen); - } - else - { - jam(); - dstptr = varAlloc(requestPtr.p->m_rowBuffer, ref, totlen); - } - + Uint32* const dstptr = rowAlloc(*collection.m_base.m_rowBuffer, ref, totlen); if (unlikely(dstptr == 0)) { jam(); return DbspjErr::OutOfRowMemory; } - memcpy(dstptr + linklen, headptr, 4 * headlen); - copy(dstptr + linklen + headlen, dataPtr); + memcpy(dstptr + offset, headptr, 4 * headlen); + copy(dstptr + offset + headlen, dataPtr); - if (linklen) + if (collection.m_type == RowCollection::COLLECTION_LIST) { jam(); NullRowRef.copyto_link(dstptr); // Null terminate list... - add_to_list(treeNodePtr.p->m_row_list, ref); + add_to_list(collection.m_list, ref); } else { jam(); - Uint32 error = add_to_map(requestPtr, treeNodePtr, row.m_src_correlation, ref); + Uint32 error = add_to_map(collection.m_map, row.m_src_correlation, ref); if (unlikely(error)) return error; } @@ -2656,30 +2648,17 @@ Dbspj::storeRow(Ptr requestPtr, * as above add_to_xxx may mave reorganized memory causing * alloced row to be moved. */ - Uint32 * rowptr = 0; - if (ref.m_allocator == 0) - { - jam(); - rowptr = get_row_ptr_stack(ref); - } - else - { - jam(); - rowptr = get_row_ptr_var(ref); - } - -//ndbrequire(rowptr==dstptr); // It moved which we now do handle - setupRowPtr(treeNodePtr, row, ref, rowptr); + const Uint32* const rowptr = get_row_ptr(ref); + setupRowPtr(collection, row, ref, rowptr); return 0; } void -Dbspj::setupRowPtr(Ptr treeNodePtr, +Dbspj::setupRowPtr(const RowCollection& collection, RowPtr& row, RowRef ref, const Uint32 * src) { - Uint32 linklen = (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP)? - 0 : 2; - const RowPtr::Header * headptr = (RowPtr::Header*)(src + linklen); + const Uint32 offset = collection.rowOffset(); + const RowPtr::Header * headptr = (RowPtr::Header*)(src + offset); Uint32 headlen = 1 + headptr->m_len; row.m_type = RowPtr::RT_LINEAR; @@ -2704,20 +2683,10 @@ Dbspj::add_to_list(SLFifoRowList & list, * add last to list */ RowRef last; - last.m_allocator = rowref.m_allocator; + last.m_alloc_type = rowref.m_alloc_type; last.m_page_id = list.m_last_row_page_id; last.m_page_pos = list.m_last_row_page_pos; - Uint32 * rowptr; - if (rowref.m_allocator == 0) - { - jam(); - rowptr = get_row_ptr_stack(last); - } - else - { - jam(); - rowptr = get_row_ptr_var(last); - } + Uint32 * const rowptr = get_row_ptr(last); rowref.copyto_link(rowptr); } @@ -2726,29 +2695,28 @@ Dbspj::add_to_list(SLFifoRowList & list, } Uint32 * -Dbspj::get_row_ptr_stack(RowRef pos) +Dbspj::get_row_ptr(RowRef pos) { - ndbassert(pos.m_allocator == 0); Ptr ptr; m_page_pool.getPtr(ptr, pos.m_page_id); - return ptr.p->m_data + pos.m_page_pos; -} - -Uint32 * -Dbspj::get_row_ptr_var(RowRef pos) -{ - ndbassert(pos.m_allocator == 1); - Ptr ptr; - m_page_pool.getPtr(ptr, pos.m_page_id); - return ((Var_page*)ptr.p)->get_ptr(pos.m_page_pos); + if (pos.m_alloc_type == BUFFER_STACK) // ::stackAlloc() memory + { + jam(); + return ptr.p->m_data + pos.m_page_pos; + } + else // ::varAlloc() memory + { + jam(); + ndbassert(pos.m_alloc_type == BUFFER_VAR); + return ((Var_page*)ptr.p)->get_ptr(pos.m_page_pos); + } } +inline bool -Dbspj::first(Ptr requestPtr, Ptr treeNodePtr, +Dbspj::first(const SLFifoRowList& list, SLFifoRowListIterator& iter) { - Uint32 var = (requestPtr.p->m_bits & Request::RT_VAR_ALLOC) != 0; - SLFifoRowList & list = treeNodePtr.p->m_row_list; if (list.isNull()) { jam(); @@ -2756,23 +2724,15 @@ Dbspj::first(Ptr requestPtr, Pt return false; } - iter.m_ref.m_allocator = var; + // const Buffer_type allocator = list.m_rowBuffer->m_type; + iter.m_ref.m_alloc_type = list.m_rowBuffer->m_type; iter.m_ref.m_page_id = list.m_first_row_page_id; iter.m_ref.m_page_pos = list.m_first_row_page_pos; - if (var == 0) - { - jam(); - iter.m_row_ptr = get_row_ptr_stack(iter.m_ref); - } - else - { - jam(); - iter.m_row_ptr = get_row_ptr_var(iter.m_ref); - } - + iter.m_row_ptr = get_row_ptr(iter.m_ref); return true; } +inline bool Dbspj::next(SLFifoRowListIterator& iter) { @@ -2782,63 +2742,25 @@ Dbspj::next(SLFifoRowListIterator& iter) jam(); return false; } - - if (iter.m_ref.m_allocator == 0) - { - jam(); - iter.m_row_ptr = get_row_ptr_stack(iter.m_ref); - } - else - { - jam(); - iter.m_row_ptr = get_row_ptr_var(iter.m_ref); - } + iter.m_row_ptr = get_row_ptr(iter.m_ref); return true; } -bool -Dbspj::next(Ptr requestPtr, Ptr treeNodePtr, - SLFifoRowListIterator& iter, SLFifoRowListIteratorPtr start) -{ - Uint32 var = (requestPtr.p->m_bits & Request::RT_VAR_ALLOC) != 0; - (void)var; - ndbassert(var == iter.m_ref.m_allocator); - if (iter.m_ref.m_allocator == 0) - { - jam(); - iter.m_row_ptr = get_row_ptr_stack(start.m_ref); - } - else - { - jam(); - iter.m_row_ptr = get_row_ptr_var(start.m_ref); - } - return next(iter); -} - Uint32 -Dbspj::add_to_map(Ptr requestPtr, Ptr treeNodePtr, +Dbspj::add_to_map(RowMap& map, Uint32 corrVal, RowRef rowref) { Uint32 * mapptr; - RowMap& map = treeNodePtr.p->m_row_map; if (map.isNull()) { jam(); - Uint16 batchsize = treeNodePtr.p->m_batch_size; - Uint32 sz16 = RowMap::MAP_SIZE_PER_REF_16 * batchsize; + ndbassert(map.m_size > 0); + ndbassert(map.m_rowBuffer != NULL); + + Uint32 sz16 = RowMap::MAP_SIZE_PER_REF_16 * map.m_size; Uint32 sz32 = (sz16 + 1) / 2; RowRef ref; - if ((requestPtr.p->m_bits & Request::RT_VAR_ALLOC) == 0) - { - jam(); - mapptr = stackAlloc(requestPtr.p->m_rowBuffer, ref, sz32); - } - else - { - jam(); - mapptr = varAlloc(requestPtr.p->m_rowBuffer, ref, sz32); - } + mapptr = rowAlloc(*map.m_rowBuffer, ref, sz32); if (unlikely(mapptr == 0)) { jam(); @@ -2846,7 +2768,6 @@ Dbspj::add_to_map(Ptr requestPt } map.assign(ref); map.m_elements = 0; - map.m_size = batchsize; map.clear(mapptr); } else @@ -2854,16 +2775,7 @@ Dbspj::add_to_map(Ptr requestPt jam(); RowRef ref; map.copyto(ref); - if (ref.m_allocator == 0) - { - jam(); - mapptr = get_row_ptr_stack(ref); - } - else - { - jam(); - mapptr = get_row_ptr_var(ref); - } + mapptr = get_row_ptr(ref); } Uint32 pos = corrVal & 0xFFFF; @@ -2885,12 +2797,11 @@ Dbspj::add_to_map(Ptr requestPt return 0; } +inline bool -Dbspj::first(Ptr requestPtr, Ptr treeNodePtr, +Dbspj::first(const RowMap& map, RowMapIterator & iter) { - Uint32 var = (requestPtr.p->m_bits & Request::RT_VAR_ALLOC) != 0; - RowMap& map = treeNodePtr.p->m_row_map; if (map.isNull()) { jam(); @@ -2898,18 +2809,9 @@ Dbspj::first(Ptr requestPtr, Pt return false; } - if (var == 0) - { - jam(); - iter.m_map_ptr = get_row_ptr_stack(map.m_map_ref); - } - else - { - jam(); - iter.m_map_ptr = get_row_ptr_var(map.m_map_ref); - } + iter.m_map_ptr = get_row_ptr(map.m_map_ref); iter.m_size = map.m_size; - iter.m_ref.m_allocator = var; + iter.m_ref.m_alloc_type = map.m_rowBuffer->m_type; Uint32 pos = 0; while (RowMap::isNull(iter.m_map_ptr, pos) && pos < iter.m_size) @@ -2926,20 +2828,12 @@ Dbspj::first(Ptr requestPtr, Pt jam(); RowMap::load(iter.m_map_ptr, pos, iter.m_ref); iter.m_element_no = pos; - if (var == 0) - { - jam(); - iter.m_row_ptr = get_row_ptr_stack(iter.m_ref); - } - else - { - jam(); - iter.m_row_ptr = get_row_ptr_var(iter.m_ref); - } + iter.m_row_ptr = get_row_ptr(iter.m_ref); return true; } } +inline bool Dbspj::next(RowMapIterator & iter) { @@ -2958,45 +2852,46 @@ Dbspj::next(RowMapIterator & iter) jam(); RowMap::load(iter.m_map_ptr, pos, iter.m_ref); iter.m_element_no = pos; - if (iter.m_ref.m_allocator == 0) - { - jam(); - iter.m_row_ptr = get_row_ptr_stack(iter.m_ref); - } - else - { - jam(); - iter.m_row_ptr = get_row_ptr_var(iter.m_ref); - } + iter.m_row_ptr = get_row_ptr(iter.m_ref); return true; } } bool -Dbspj::next(Ptr requestPtr, Ptr treeNodePtr, - RowMapIterator & iter, RowMapIteratorPtr start) +Dbspj::first(const RowCollection& collection, + RowIterator& iter) { - Uint32 var = (requestPtr.p->m_bits & Request::RT_VAR_ALLOC) != 0; - RowMap& map = treeNodePtr.p->m_row_map; - ndbrequire(!map.isNull()); - - if (var == 0) + iter.m_type = collection.m_type; + if (iter.m_type == RowCollection::COLLECTION_LIST) { jam(); - iter.m_map_ptr = get_row_ptr_stack(map.m_map_ref); + return first(collection.m_list, iter.m_list); } else { jam(); - iter.m_map_ptr = get_row_ptr_var(map.m_map_ref); + ndbassert(iter.m_type == RowCollection::COLLECTION_MAP); + return first(collection.m_map, iter.m_map); } - iter.m_size = map.m_size; +} - RowMap::load(iter.m_map_ptr, start.m_element_no, iter.m_ref); - iter.m_element_no = start.m_element_no; - return next(iter); +bool +Dbspj::next(RowIterator& iter) +{ + if (iter.m_type == RowCollection::COLLECTION_LIST) + { + jam(); + return next(iter.m_list); + } + else + { + jam(); + ndbassert(iter.m_type == RowCollection::COLLECTION_MAP); + return next(iter.m_map); + } } +inline Uint32 * Dbspj::stackAlloc(RowBuffer & buffer, RowRef& dst, Uint32 sz) { @@ -3025,11 +2920,12 @@ Dbspj::stackAlloc(RowBuffer & buffer, Ro dst.m_page_id = ptr.i; dst.m_page_pos = pos; - dst.m_allocator = 0; + dst.m_alloc_type = BUFFER_STACK; buffer.m_stack.m_pos = pos + sz; return ptr.p->m_data + pos; } +inline Uint32 * Dbspj::varAlloc(RowBuffer & buffer, RowRef& dst, Uint32 sz) { @@ -3061,11 +2957,32 @@ Dbspj::varAlloc(RowBuffer & buffer, RowR dst.m_page_id = ptr.i; dst.m_page_pos = pos; - dst.m_allocator = 1; + dst.m_alloc_type = BUFFER_VAR; buffer.m_var.m_free = vp->free_space; return vp->get_ptr(pos); } +Uint32 * +Dbspj::rowAlloc(RowBuffer& rowBuffer, RowRef& dst, Uint32 sz) +{ + if (rowBuffer.m_type == BUFFER_STACK) + { + jam(); + return stackAlloc(rowBuffer, dst, sz); + } + else if (rowBuffer.m_type == BUFFER_VAR) + { + jam(); + return varAlloc(rowBuffer, dst, sz); + } + else + { + jam(); + ndbrequire(false); + return NULL; + } +} + bool Dbspj::allocPage(Ptr & ptr) { @@ -7523,49 +7440,28 @@ Dbspj::appendFromParent(Uint32 & dst, Lo m_treenode_pool.getPtr(treeNodePtr, treeNodePtr.p->m_parentPtrI); DEBUG("appendFromParent" << ", node: " << treeNodePtr.p->m_node_no); - if (unlikely((treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER_MAP) == 0)) + if (unlikely(treeNodePtr.p->m_rows.m_type != RowCollection::COLLECTION_MAP)) { DEBUG_CRASH(); return DbspjErr::InvalidPattern; } RowRef ref; - treeNodePtr.p->m_row_map.copyto(ref); - Uint32 allocator = ref.m_allocator; - const Uint32 * mapptr; - if (allocator == 0) - { - jam(); - mapptr = get_row_ptr_stack(ref); - } - else - { - jam(); - mapptr = get_row_ptr_var(ref); - } + treeNodePtr.p->m_rows.m_map.copyto(ref); + const Uint32* const mapptr = get_row_ptr(ref); Uint32 pos = corrVal >> 16; // parent corr-val - if (unlikely(! (pos < treeNodePtr.p->m_row_map.m_size))) + if (unlikely(! (pos < treeNodePtr.p->m_rows.m_map.m_size))) { DEBUG_CRASH(); return DbspjErr::InvalidPattern; } // load ref to parent row - treeNodePtr.p->m_row_map.load(mapptr, pos, ref); + treeNodePtr.p->m_rows.m_map.load(mapptr, pos, ref); - const Uint32 * rowptr; - if (allocator == 0) - { - jam(); - rowptr = get_row_ptr_stack(ref); - } - else - { - jam(); - rowptr = get_row_ptr_var(ref); - } - setupRowPtr(treeNodePtr, targetRow, ref, rowptr); + const Uint32* const rowptr = get_row_ptr(ref); + setupRowPtr(treeNodePtr.p->m_rows, targetRow, ref, rowptr); if (levels) { === modified file 'storage/ndb/src/mgmsrv/testConfig.cpp' --- a/storage/ndb/src/mgmsrv/testConfig.cpp 2011-02-02 00:40:07 +0000 +++ b/storage/ndb/src/mgmsrv/testConfig.cpp 2012-11-12 13:42:48 +0000 @@ -302,19 +302,19 @@ print_restart_info(void) } fprintf(stderr, "*** initial node restart ***\n"); - for (size_t i = 0; i < initial_node.size(); i++) { + for (unsigned i = 0; i < initial_node.size(); i++) { fprintf(stderr, "%s\n", initial_node[i]); } fprintf(stderr, "\n"); fprintf(stderr, "*** system restart ***\n"); - for (size_t i = 0; i < system.size(); i++) { + for (unsigned i = 0; i < system.size(); i++) { fprintf(stderr, "%s\n", system[i]); } fprintf(stderr, "\n"); fprintf(stderr, "*** initial system restart ***\n"); - for (size_t i = 0; i < initial_system.size(); i++) { + for (unsigned i = 0; i < initial_system.size(); i++) { fprintf(stderr, "%s\n", initial_system[i]); } fprintf(stderr, "\n"); === modified file 'storage/ndb/test/ndbapi/testInterpreter.cpp' --- a/storage/ndb/test/ndbapi/testInterpreter.cpp 2011-07-05 12:46:07 +0000 +++ b/storage/ndb/test/ndbapi/testInterpreter.cpp 2012-11-12 13:26:01 +0000 @@ -209,9 +209,10 @@ int runTestBug19537(NDBT_Context* ctx, N // Load 64-bit constant into register 1 and // write from register 1 to 32-bit column KOL2 const Uint64 reg_val = 0x0102030405060708ULL; +#if 0 Uint32 reg_ptr32[2]; - memcpy(reg_ptr32+0, (Uint8*)®_val, sizeof(Uint32)); - memcpy(reg_ptr32+1, ((Uint8*)®_val)+4, sizeof(Uint32)); + memcpy(&(reg_ptr32[0]), (Uint8*)®_val, sizeof(Uint32)); + memcpy(&(reg_ptr32[1]), ((Uint8*)®_val)+4, sizeof(Uint32)); if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) { g_err << "runTestBug19537: platform is LITTLE endian" << endl; } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) { @@ -222,6 +223,7 @@ int runTestBug19537(NDBT_Context* ctx, N pNdb->closeTransaction(pTrans); return NDBT_FAILED; } +#endif if (pOp->load_const_u64(1, reg_val) == -1 || pOp->write_attr("KOL2", 1) == -1) { No bundle (reason: useless for push emails).