@@ -8714,6 +8714,139 @@ int runTestStartNode(NDBT_Context* ctx, NDBT_Step* step){
8714
8714
return NDBT_OK;
8715
8715
}
8716
8716
8717
+ /* *
8718
+ * In Partial LCP we need many LCPs to restore a checkpoint. The
8719
+ * maximum number of LCPs we need in order to restore a checkpoint
8720
+ * is 2048. This test uses error insert 10048 to ensure that each
8721
+ * LCP only stores 1 part completely. This means that this test
8722
+ * can generate checkpoints that have to write LCP control files
8723
+ * consisting of close to 2048 parts and similarly to restore those.
8724
+ *
8725
+ * The test loops for more than 2048 times to ensure that we come
8726
+ * to a situation with a large number of parts in each LCP and in
8727
+ * particular for the last one that we are to restore. The number
8728
+ * 2058 is somewhat arbitrarily choosen to ensure this.
8729
+ *
8730
+ * The test case is hardcoded to make those special LCPs in node 2.
8731
+ *
8732
+ * Between each LCP we perform a random amount of updates to ensure
8733
+ * that each part of this table will create a non-empty LCP. We
8734
+ * insert a number of random LCPs that are empty as well to ensure
8735
+ * that we generate empty LCPs correctly as well even if there are
8736
+ * many parts in the LCP.
8737
+ */
8738
+ int run_PLCP_many_parts (NDBT_Context *ctx, NDBT_Step *step)
8739
+ {
8740
+ Ndb *pNdb = GETNDB (step);
8741
+ int loops = 2108 ;
8742
+ int result = NDBT_OK;
8743
+ int records = ctx->getNumRecords ();
8744
+ HugoTransactions hugoTrans (*ctx->getTab ());
8745
+ NdbRestarter restarter;
8746
+ int i = 0 ;
8747
+ const Uint32 nodeCount = restarter.getNumDbNodes ();
8748
+ int nodeId = 2 ;
8749
+ HugoOperations hugoOps (*ctx->getTab ());
8750
+ if (nodeCount < 2 )
8751
+ {
8752
+ return NDBT_OK; /* Requires at least 2 nodes to run */
8753
+ }
8754
+ if (hugoTrans.loadTable (pNdb, records) != NDBT_OK)
8755
+ {
8756
+ g_err << " Failed to load table" << endl;
8757
+ return NDBT_FAILED;
8758
+ }
8759
+
8760
+ g_err << " Executing " << loops << " loops" << endl;
8761
+ while (++i <= loops && result != NDBT_FAILED)
8762
+ {
8763
+ g_err << " Start loop " << i << endl;
8764
+ ndbout << " Start an LCP" << endl;
8765
+ {
8766
+ if (restarter.insertErrorInNode (nodeId, 10048 ) != 0 )
8767
+ {
8768
+ g_err << " ERROR: Error insert 10048 failed" << endl;
8769
+ return NDBT_FAILED;
8770
+ }
8771
+ int val = DumpStateOrd::DihStartLcpImmediately;
8772
+ if (restarter.dumpStateAllNodes (&val, 1 ) != 0 )
8773
+ {
8774
+ g_err << " ERR: " << step->getName ()
8775
+ << " failed on line " << __LINE__ << endl;
8776
+ return NDBT_FAILED;
8777
+ }
8778
+ }
8779
+ bool skip = false ;
8780
+ if ((i % 50 ) == 0 )
8781
+ {
8782
+ skip = true ;
8783
+ }
8784
+ Uint32 batch = 4 ;
8785
+ Uint32 row;
8786
+ if (!skip)
8787
+ {
8788
+ row = rand () % records;
8789
+ if (row + batch > (Uint32)records)
8790
+ batch = records - row;
8791
+
8792
+ if ((hugoOps.startTransaction (pNdb) != 0 ) ||
8793
+ (hugoOps.pkUpdateRecord (pNdb, row, batch, rand ()) != 0 ) ||
8794
+ (hugoOps.execute_Commit (pNdb)) ||
8795
+ (hugoOps.closeTransaction (pNdb)))
8796
+ {
8797
+ g_err << " Update failed" << endl;
8798
+ // return NDBT_FAILED;
8799
+ }
8800
+ }
8801
+ NdbSleep_SecSleep (1 );
8802
+ if (!skip)
8803
+ {
8804
+ row = rand () % records;
8805
+ if (row + batch > (Uint32)records)
8806
+ batch = records - row;
8807
+ if ((hugoOps.startTransaction (pNdb) != 0 ) ||
8808
+ (hugoOps.pkUpdateRecord (pNdb, row, batch, rand ()) != 0 ) ||
8809
+ (hugoOps.execute_Commit (pNdb)) ||
8810
+ (hugoOps.closeTransaction (pNdb)))
8811
+ {
8812
+ g_err << " Update failed" << endl;
8813
+ // return NDBT_FAILED;
8814
+ }
8815
+ }
8816
+ }
8817
+ /* *
8818
+ * Finally after creating a complex restore situation we test this
8819
+ * by restarting node 2 to ensure that we can also recover the
8820
+ * complex LCP setup.
8821
+ */
8822
+ ndbout << " Restart node 2" << endl;
8823
+ if (restarter.restartOneDbNode (nodeId,
8824
+ false , /* initial */
8825
+ true , /* nostart */
8826
+ false , /* abort */
8827
+ false /* force */ ) != 0 )
8828
+ {
8829
+ g_err << " Restart failed" << endl;
8830
+ return NDBT_FAILED;
8831
+ }
8832
+ ndbout << " Wait for NoStart state" << endl;
8833
+ restarter.waitNodesNoStart (&nodeId, 1 );
8834
+ ndbout << " Start node" << endl;
8835
+ if (restarter.startNodes (&nodeId, 1 ) != 0 )
8836
+ {
8837
+ g_err << " Start failed" << endl;
8838
+ return NDBT_FAILED;
8839
+ }
8840
+ ndbout << " Waiting for node to start" << endl;
8841
+ if (restarter.waitNodesStarted (&nodeId, 1 ) != 0 )
8842
+ {
8843
+ g_err << " Wait node start failed" << endl;
8844
+ return NDBT_FAILED;
8845
+ }
8846
+ ndbout << " Test complete" << endl;
8847
+ return NDBT_OK;
8848
+ }
8849
+
8717
8850
int run_PLCP_I1 (NDBT_Context *ctx, NDBT_Step *step)
8718
8851
{
8719
8852
Ndb *pNdb = GETNDB (step);
@@ -9591,6 +9724,11 @@ TESTCASE("MultiCrashTest",
9591
9724
STEP (runMultiCrashTest);
9592
9725
FINALIZER (runClearTable);
9593
9726
}
9727
+ TESTCASE (" LCP_with_many_parts" ,
9728
+ " Ensure that LCP has many parts" )
9729
+ {
9730
+ INITIALIZER (run_PLCP_many_parts);
9731
+ }
9594
9732
TESTCASE (" PLCP_I1" ,
9595
9733
" Initial node restart while deleting rows" )
9596
9734
{
0 commit comments