mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 22:12:30 +01:00
ee740746af
BitKeeper/deleted/.del-MetaData.cpp~146ae9865dd35829: Delete: storage/ndb/src/kernel/vm/MetaData.cpp BitKeeper/deleted/.del-MetaData.hpp~538342afcd8ac53c: Delete: storage/ndb/src/kernel/vm/MetaData.hpp BitKeeper/deleted/.del-DbtupLCP.cpp~855b1ed3fbc86a42: Delete: storage/ndb/src/kernel/blocks/dbtup/DbtupLCP.cpp BitKeeper/deleted/.del-DbtupSystemRestart.cpp~15b54d7e4e75d2d: Delete: storage/ndb/src/kernel/blocks/dbtup/DbtupSystemRestart.cpp BitKeeper/deleted/.del-DbtupUndoLog.cpp~5a2ef6e86b1404e9: Delete: storage/ndb/src/kernel/blocks/dbtup/DbtupUndoLog.cpp storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/CreateFilegroup.hpp'' storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/CreateFilegroupImpl.hpp'' storage/ndb/include/kernel/signaldata/CreateObj.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/CreateObj.hpp'' storage/ndb/include/kernel/signaldata/DictObjOp.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/DictObjOp.hpp'' storage/ndb/include/kernel/signaldata/DropFilegroup.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/DropFilegroup.hpp'' storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/DropFilegroupImpl.hpp'' storage/ndb/include/kernel/signaldata/DropObj.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/DropObj.hpp'' storage/ndb/include/kernel/signaldata/Extent.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/Extent.hpp'' storage/ndb/include/kernel/signaldata/LgmanContinueB.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/LgmanContinueB.hpp'' storage/ndb/include/kernel/signaldata/PgmanContinueB.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/PgmanContinueB.hpp'' storage/ndb/include/kernel/signaldata/RestoreContinueB.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/RestoreContinueB.hpp'' storage/ndb/include/kernel/signaldata/RestoreImpl.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/RestoreImpl.hpp'' storage/ndb/include/kernel/signaldata/TsmanContinueB.hpp: New BitKeeper file ``storage/ndb/include/kernel/signaldata/TsmanContinueB.hpp'' storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbdih/printSysfile.cpp'' storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp'' storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp'' storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.cpp'' storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/Undo_buffer.hpp'' storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp'' storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp'' storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp'' storage/ndb/src/kernel/blocks/diskpage.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/diskpage.cpp'' storage/ndb/src/kernel/blocks/diskpage.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/diskpage.hpp'' storage/ndb/src/kernel/blocks/lgman.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/lgman.cpp'' storage/ndb/src/kernel/blocks/lgman.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/lgman.hpp'' storage/ndb/src/kernel/blocks/pgman.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/pgman.cpp'' storage/ndb/src/kernel/blocks/pgman.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/pgman.hpp'' storage/ndb/src/kernel/blocks/print_file.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/print_file.cpp'' storage/ndb/src/kernel/blocks/restore.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/restore.cpp'' storage/ndb/src/kernel/blocks/restore.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/restore.hpp'' storage/ndb/src/kernel/blocks/tsman.cpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/tsman.cpp'' storage/ndb/src/kernel/blocks/tsman.hpp: New BitKeeper file ``storage/ndb/src/kernel/blocks/tsman.hpp'' storage/ndb/src/kernel/vm/DLCFifoList.hpp: New BitKeeper file ``storage/ndb/src/kernel/vm/DLCFifoList.hpp'' storage/ndb/src/kernel/vm/DLCHashTable.hpp: New BitKeeper file ``storage/ndb/src/kernel/vm/DLCHashTable.hpp'' storage/ndb/src/kernel/vm/KeyTable2Ref.hpp: New BitKeeper file ``storage/ndb/src/kernel/vm/KeyTable2Ref.hpp'' storage/ndb/src/kernel/vm/Rope.cpp: New BitKeeper file ``storage/ndb/src/kernel/vm/Rope.cpp'' storage/ndb/src/kernel/vm/Rope.hpp: New BitKeeper file ``storage/ndb/src/kernel/vm/Rope.hpp''
543 lines
14 KiB
C++
543 lines
14 KiB
C++
|
|
#include <NDBT.hpp>
|
|
#include <NdbApi.hpp>
|
|
#include <NdbRestarter.hpp>
|
|
#include <HugoOperations.hpp>
|
|
#include <HugoTransactions.hpp>
|
|
#include <UtilTransactions.hpp>
|
|
#include <signaldata/DumpStateOrd.hpp>
|
|
|
|
#include <getarg.h>
|
|
#include <InputStream.hpp>
|
|
|
|
struct CASE
|
|
{
|
|
bool start_row;
|
|
bool end_row;
|
|
bool curr_row;
|
|
const char * op1;
|
|
const char * op2;
|
|
const char * op3;
|
|
int val;
|
|
};
|
|
|
|
static CASE g_op_types[] =
|
|
{
|
|
{ false, true, false, "INS", 0, 0, 0 }, // 0x001 a
|
|
{ true, true, false, "UPD", 0, 0, 0 }, // 0x002 d
|
|
{ true, false, false, "DEL", 0, 0, 0 }, // 0x004 g
|
|
|
|
{ false, true, false, "INS", "UPD", 0, 0 }, // 0x008 b
|
|
{ false, false, false, "INS", "DEL", 0, 0 }, // 0x010 c
|
|
{ true, true, false, "UPD", "UPD", 0, 0 }, // 0x020 e
|
|
{ true, false, false, "UPD", "DEL", 0, 0 }, // 0x040 f
|
|
{ true, true, false, "DEL", "INS", 0, 0 }, // 0x080 h
|
|
|
|
{ false, true, false, "INS", "DEL", "INS", 0 }, // 0x100 i
|
|
{ true, false, false, "DEL", "INS", "DEL", 0 } // 0x200 j
|
|
};
|
|
const size_t OP_COUNT = (sizeof(g_op_types)/sizeof(g_op_types[0]));
|
|
|
|
static Ndb* g_ndb = 0;
|
|
static CASE* g_ops;
|
|
static Ndb_cluster_connection *g_cluster_connection= 0;
|
|
static HugoOperations* g_hugo_ops;
|
|
static int g_use_ops = 1 | 2 | 4;
|
|
static int g_cases = 0x1;
|
|
static int g_case_loop = 2;
|
|
static int g_rows = 10;
|
|
static int g_setup_tables = 1;
|
|
static int g_one_op_at_a_time = 0;
|
|
static const char * g_tablename = "T1";
|
|
static const NdbDictionary::Table* g_table = 0;
|
|
static NdbRestarter g_restarter;
|
|
|
|
static int init_ndb(int argc, char** argv);
|
|
static int parse_args(int argc, char** argv);
|
|
static int connect_ndb();
|
|
static int drop_all_tables();
|
|
static int load_table();
|
|
static int pause_lcp(int error);
|
|
static int do_op(int row);
|
|
static int continue_lcp(int error = 0);
|
|
static int commit();
|
|
static int restart();
|
|
static int validate();
|
|
|
|
#define require(x) { bool b = x; if(!b){g_err << __LINE__ << endl; abort();}}
|
|
|
|
int
|
|
main(int argc, char ** argv){
|
|
ndb_init();
|
|
require(!init_ndb(argc, argv));
|
|
if(parse_args(argc, argv))
|
|
return -1;
|
|
require(!connect_ndb());
|
|
|
|
if(g_setup_tables){
|
|
require(!drop_all_tables());
|
|
|
|
if(NDBT_Tables::createTable(g_ndb, g_tablename) != 0){
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
g_table = g_ndb->getDictionary()->getTable(g_tablename);
|
|
if(g_table == 0){
|
|
g_err << "Failed to retreive table: " << g_tablename << endl;
|
|
exit(-1);
|
|
}
|
|
require(g_hugo_ops = new HugoOperations(* g_table));
|
|
require(!g_hugo_ops->startTransaction(g_ndb));
|
|
|
|
g_ops= new CASE[g_rows];
|
|
|
|
const int use_ops = g_use_ops;
|
|
for(size_t i = 0; i<OP_COUNT; i++)
|
|
{
|
|
if(g_one_op_at_a_time){
|
|
while(i < OP_COUNT && (use_ops & (1 << i)) == 0) i++;
|
|
if(i == OP_COUNT)
|
|
break;
|
|
ndbout_c("-- loop\noperation: %c use_ops: %x", 'a'+i, use_ops);
|
|
g_use_ops = (1 << i);
|
|
} else {
|
|
i = OP_COUNT - 1;
|
|
}
|
|
|
|
size_t test_case = 0;
|
|
if((1 << test_case++) & g_cases)
|
|
{
|
|
for(size_t tl = 0; tl<g_case_loop; tl++){
|
|
g_info << "Performing all ops wo/ inteference of LCP" << endl;
|
|
|
|
g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl;
|
|
g_info << " where ZLCP_OP_WRITE_RT_BREAK is "
|
|
" finished before SAVE_PAGES" << endl;
|
|
require(!load_table());
|
|
require(!pause_lcp(5900));
|
|
for(size_t j = 0; j<g_rows; j++){
|
|
require(!do_op(j));
|
|
}
|
|
require(!continue_lcp(5900));
|
|
require(!commit());
|
|
require(!pause_lcp(5900));
|
|
require(!restart());
|
|
require(!validate());
|
|
}
|
|
}
|
|
|
|
if((1 << test_case++) & g_cases)
|
|
{
|
|
for(size_t tl = 0; tl<g_case_loop; tl++){
|
|
g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl;
|
|
g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished after SAVE_PAGES"
|
|
<< endl;
|
|
require(!load_table());
|
|
require(!pause_lcp(5901));
|
|
for(size_t j = 0; j<g_rows; j++){
|
|
require(!do_op(j));
|
|
}
|
|
require(!continue_lcp(5901));
|
|
require(!commit());
|
|
require(!pause_lcp(5900));
|
|
require(!restart());
|
|
require(!validate());
|
|
}
|
|
}
|
|
|
|
if((1 << test_case++) & g_cases)
|
|
{
|
|
for(size_t tl = 0; tl<g_case_loop; tl++){
|
|
g_info << "Testing pre LCP operations, undo-ed at commit" << endl;
|
|
require(!load_table());
|
|
require(!pause_lcp(5902));
|
|
for(size_t j = 0; j<g_rows; j++){
|
|
require(!do_op(j));
|
|
}
|
|
require(!continue_lcp(5902));
|
|
require(!commit());
|
|
require(!continue_lcp(5903));
|
|
require(!pause_lcp(5900));
|
|
require(!restart());
|
|
require(!validate());
|
|
}
|
|
}
|
|
|
|
if((1 << test_case++) & g_cases)
|
|
{
|
|
for(size_t tl = 0; tl<g_case_loop; tl++){
|
|
g_info << "Testing prepared during LCP and committed after" << endl;
|
|
require(!load_table());
|
|
require(!pause_lcp(5904)); // Start LCP, but don't save pages
|
|
for(size_t j = 0; j<g_rows; j++){
|
|
require(!do_op(j));
|
|
}
|
|
require(!continue_lcp(5904)); // Start ACC save pages
|
|
require(!pause_lcp(5900)); // Next LCP
|
|
require(!commit());
|
|
require(!restart());
|
|
require(!validate());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static int init_ndb(int argc, char** argv)
|
|
{
|
|
ndb_init();
|
|
return 0;
|
|
}
|
|
|
|
static int parse_args(int argc, char** argv)
|
|
{
|
|
size_t i;
|
|
char * ops= 0, *cases=0;
|
|
struct getargs args[] = {
|
|
{ "records", 0, arg_integer, &g_rows, "Number of records", "records" },
|
|
{ "operations", 'o', arg_string, &ops, "Operations [a-h]", 0 },
|
|
{ "1", '1', arg_flag, &g_one_op_at_a_time, "One op at a time", 0 },
|
|
{ "0", '0', arg_negative_flag, &g_one_op_at_a_time, "All ops at once", 0 },
|
|
{ "cases", 'c', arg_string, &cases, "Cases [a-c]", 0 },
|
|
{ 0, 't', arg_flag, &g_setup_tables, "Create table", 0 },
|
|
{ 0, 'u', arg_negative_flag, &g_setup_tables, "Dont create table", 0 }
|
|
};
|
|
|
|
int optind= 0;
|
|
const int num_args = sizeof(args)/sizeof(args[0]);
|
|
if(getarg(args, num_args, argc, (const char**)argv, &optind)) {
|
|
arg_printusage(args, num_args, argv[0], " tabname1\n");
|
|
ndbout_c("\n -- Operations [a-%c] = ", 'a'+OP_COUNT-1);
|
|
for(i = 0; i<OP_COUNT; i++){
|
|
ndbout_c("\t%c = %s %s",
|
|
'a'+i, g_op_types[i].op1,
|
|
g_op_types[i].op2 ? g_op_types[i].op2 : "");
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if(ops != 0){
|
|
g_use_ops = 0;
|
|
char * s = ops;
|
|
while(* s)
|
|
g_use_ops |= (1 << ((* s++) - 'a'));
|
|
}
|
|
|
|
if(cases != 0){
|
|
g_cases = 0;
|
|
char * s = cases;
|
|
while(* s)
|
|
g_cases |= (1 << ((* s++) - 'a'));
|
|
}
|
|
|
|
ndbout_c("table: %s", g_tablename);
|
|
printf("operations: ");
|
|
for(i = 0; i<OP_COUNT; i++)
|
|
if(g_use_ops & (1 << i))
|
|
printf("%c", 'a'+i);
|
|
printf("\n");
|
|
|
|
printf("test cases: ");
|
|
for(i = 0; i<3; i++)
|
|
if(g_cases & (1 << i))
|
|
printf("%c", '1'+i);
|
|
printf("\n");
|
|
printf("-------------\n");
|
|
return 0;
|
|
}
|
|
|
|
static int connect_ndb()
|
|
{
|
|
g_cluster_connection = new Ndb_cluster_connection();
|
|
if(g_cluster_connection->connect(12, 5, 1) != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
g_ndb = new Ndb(g_cluster_connection, "TEST_DB");
|
|
g_ndb->init(256);
|
|
if(g_ndb->waitUntilReady(30) == 0){
|
|
return 0;
|
|
// int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP };
|
|
// return g_restarter.dumpStateAllNodes(args, 1);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static int disconnect_ndb()
|
|
{
|
|
delete g_ndb;
|
|
delete g_cluster_connection;
|
|
g_ndb = 0;
|
|
g_table = 0;
|
|
g_cluster_connection= 0;
|
|
return 0;
|
|
}
|
|
|
|
static int drop_all_tables()
|
|
{
|
|
NdbDictionary::Dictionary * dict = g_ndb->getDictionary();
|
|
require(dict);
|
|
|
|
BaseString db = g_ndb->getDatabaseName();
|
|
BaseString schema = g_ndb->getSchemaName();
|
|
|
|
NdbDictionary::Dictionary::List list;
|
|
if (dict->listObjects(list, NdbDictionary::Object::TypeUndefined) == -1){
|
|
g_err << "Failed to list tables: " << endl
|
|
<< dict->getNdbError() << endl;
|
|
return -1;
|
|
}
|
|
for (unsigned i = 0; i < list.count; i++) {
|
|
NdbDictionary::Dictionary::List::Element& elt = list.elements[i];
|
|
switch (elt.type) {
|
|
case NdbDictionary::Object::SystemTable:
|
|
case NdbDictionary::Object::UserTable:
|
|
g_ndb->setDatabaseName(elt.database);
|
|
g_ndb->setSchemaName(elt.schema);
|
|
if(dict->dropTable(elt.name) != 0){
|
|
g_err << "Failed to drop table: "
|
|
<< elt.database << "/" << elt.schema << "/" << elt.name <<endl;
|
|
g_err << dict->getNdbError() << endl;
|
|
return -1;
|
|
}
|
|
break;
|
|
case NdbDictionary::Object::UniqueHashIndex:
|
|
case NdbDictionary::Object::OrderedIndex:
|
|
case NdbDictionary::Object::HashIndexTrigger:
|
|
case NdbDictionary::Object::IndexTrigger:
|
|
case NdbDictionary::Object::SubscriptionTrigger:
|
|
case NdbDictionary::Object::ReadOnlyConstraint:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_ndb->setDatabaseName(db.c_str());
|
|
g_ndb->setSchemaName(schema.c_str());
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int load_table()
|
|
{
|
|
UtilTransactions clear(* g_table);
|
|
require(!clear.clearTable(g_ndb));
|
|
|
|
HugoOperations ops(* g_table);
|
|
require(!ops.startTransaction(g_ndb));
|
|
size_t op = 0;
|
|
size_t rows = 0;
|
|
size_t uncommitted = 0;
|
|
bool prepared = false;
|
|
for(size_t i = 0; i<g_rows; i++){
|
|
for(op %= OP_COUNT; !((1 << op) & g_use_ops); op = (op + 1) % OP_COUNT);
|
|
g_ops[i] = g_op_types[op++];
|
|
if(g_ops[i].start_row){
|
|
g_ops[i].curr_row = true;
|
|
g_ops[i].val = rand();
|
|
require(!ops.pkInsertRecord(g_ndb, i, 1, g_ops[i].val));
|
|
uncommitted++;
|
|
} else {
|
|
g_ops[i].curr_row = false;
|
|
}
|
|
if(uncommitted >= 100){
|
|
require(!ops.execute_Commit(g_ndb));
|
|
require(!ops.getTransaction()->restart());
|
|
rows += uncommitted;
|
|
uncommitted = 0;
|
|
}
|
|
}
|
|
if(uncommitted)
|
|
require(!ops.execute_Commit(g_ndb));
|
|
|
|
require(!ops.closeTransaction(g_ndb));
|
|
rows += uncommitted;
|
|
g_info << "Inserted " << rows << " rows" << endl;
|
|
return 0;
|
|
}
|
|
|
|
static int pause_lcp(int error)
|
|
{
|
|
int nodes = g_restarter.getNumDbNodes();
|
|
|
|
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_INFO, 0 };
|
|
int fd = ndb_mgm_listen_event(g_restarter.handle, filter);
|
|
require(fd >= 0);
|
|
require(!g_restarter.insertErrorInAllNodes(error));
|
|
int dump[] = { DumpStateOrd::DihStartLcpImmediately };
|
|
require(!g_restarter.dumpStateAllNodes(dump, 1));
|
|
|
|
char *tmp;
|
|
char buf[1024];
|
|
SocketInputStream in(fd, 1000);
|
|
int count = 0;
|
|
do {
|
|
tmp = in.gets(buf, 1024);
|
|
if(tmp)
|
|
{
|
|
int id;
|
|
if(sscanf(tmp, "%*[^:]: LCP: %d ", &id) == 1 && id == error &&
|
|
--nodes == 0){
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
}
|
|
} while(count++ < 30);
|
|
|
|
close(fd);
|
|
return -1;
|
|
}
|
|
|
|
static int do_op(int row)
|
|
{
|
|
HugoOperations & ops = * g_hugo_ops;
|
|
if(strcmp(g_ops[row].op1, "INS") == 0){
|
|
require(!g_ops[row].curr_row);
|
|
g_ops[row].curr_row = true;
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkInsertRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op1, "UPD") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkUpdateRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op1, "DEL") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].curr_row = false;
|
|
require(!ops.pkDeleteRecord(g_ndb, row, 1));
|
|
}
|
|
|
|
require(!ops.execute_NoCommit(g_ndb));
|
|
|
|
if(g_ops[row].op2 == 0){
|
|
} else if(strcmp(g_ops[row].op2, "INS") == 0){
|
|
require(!g_ops[row].curr_row);
|
|
g_ops[row].curr_row = true;
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkInsertRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op2, "UPD") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkUpdateRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op2, "DEL") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].curr_row = false;
|
|
require(!ops.pkDeleteRecord(g_ndb, row, 1));
|
|
}
|
|
|
|
if(g_ops[row].op2 != 0)
|
|
require(!ops.execute_NoCommit(g_ndb));
|
|
|
|
if(g_ops[row].op3 == 0){
|
|
} else if(strcmp(g_ops[row].op3, "INS") == 0){
|
|
require(!g_ops[row].curr_row);
|
|
g_ops[row].curr_row = true;
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkInsertRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op3, "UPD") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].val = rand();
|
|
require(!ops.pkUpdateRecord(g_ndb, row, 1, g_ops[row].val));
|
|
} else if(strcmp(g_ops[row].op3, "DEL") == 0){
|
|
require(g_ops[row].curr_row);
|
|
g_ops[row].curr_row = false;
|
|
require(!ops.pkDeleteRecord(g_ndb, row, 1));
|
|
}
|
|
|
|
if(g_ops[row].op3 != 0)
|
|
require(!ops.execute_NoCommit(g_ndb));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int continue_lcp(int error)
|
|
{
|
|
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_INFO, 0 };
|
|
int fd = -1;
|
|
if(error){
|
|
fd = ndb_mgm_listen_event(g_restarter.handle, filter);
|
|
require(fd >= 0);
|
|
}
|
|
|
|
int args[] = { DumpStateOrd::LCPContinue };
|
|
if(g_restarter.dumpStateAllNodes(args, 1) != 0)
|
|
return -1;
|
|
|
|
if(error){
|
|
char *tmp;
|
|
char buf[1024];
|
|
SocketInputStream in(fd, 1000);
|
|
int count = 0;
|
|
int nodes = g_restarter.getNumDbNodes();
|
|
do {
|
|
tmp = in.gets(buf, 1024);
|
|
if(tmp)
|
|
{
|
|
int id;
|
|
if(sscanf(tmp, "%*[^:]: LCP: %d ", &id) == 1 && id == error &&
|
|
--nodes == 0){
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
}
|
|
} while(count++ < 30);
|
|
|
|
close(fd);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int commit()
|
|
{
|
|
HugoOperations & ops = * g_hugo_ops;
|
|
int res = ops.execute_Commit(g_ndb);
|
|
if(res == 0){
|
|
return ops.getTransaction()->restart();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static int restart()
|
|
{
|
|
g_info << "Restarting cluster" << endl;
|
|
g_hugo_ops->closeTransaction(g_ndb);
|
|
disconnect_ndb();
|
|
delete g_hugo_ops;
|
|
|
|
require(!g_restarter.restartAll());
|
|
require(!g_restarter.waitClusterStarted(30));
|
|
require(!connect_ndb());
|
|
|
|
g_table = g_ndb->getDictionary()->getTable(g_tablename);
|
|
require(g_table);
|
|
require(g_hugo_ops = new HugoOperations(* g_table));
|
|
require(!g_hugo_ops->startTransaction(g_ndb));
|
|
return 0;
|
|
}
|
|
|
|
static int validate()
|
|
{
|
|
HugoOperations ops(* g_table);
|
|
for(size_t i = 0; i<g_rows; i++){
|
|
require(g_ops[i].curr_row == g_ops[i].end_row);
|
|
require(!ops.startTransaction(g_ndb));
|
|
ops.pkReadRecord(g_ndb, i, 1);
|
|
int res = ops.execute_Commit(g_ndb);
|
|
if(g_ops[i].curr_row){
|
|
require(res == 0 && ops.verifyUpdatesValue(g_ops[i].val) == 0);
|
|
} else {
|
|
require(res == 626);
|
|
}
|
|
ops.closeTransaction(g_ndb);
|
|
}
|
|
|
|
for(size_t j = 0; j<10; j++){
|
|
UtilTransactions clear(* g_table);
|
|
require(!clear.clearTable(g_ndb));
|
|
|
|
HugoTransactions trans(* g_table);
|
|
require(trans.loadTable(g_ndb, 1024) == 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|