Skip to content

Commit 4ab8bac

Browse files
Merge branch 'cassandra-6.0' into trunk
* cassandra-6.0: Clarify the unset, true and false behaviours of cassandra.reset_bootstrap_progress
2 parents 617fd3b + 05fecbc commit 4ab8bac

3 files changed

Lines changed: 45 additions & 9 deletions

File tree

‎CHANGES.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Merged from 6.0:
6666
* Avoid megamorphic calls when serializing and deserializing fixed-length values (CASSANDRA-21536)
6767
* Avoid megamorphic calls for Cell.timestamp/ttl/path/localDeletionTimeAsUnsignedInt methods (CASSANDRA-21526)
6868
Merged from 5.0:
69+
* Clarify the unset, true and false behaviours of cassandra.reset_bootstrap_progress in the abort message and docs (CASSANDRA-21595)
6970
* Isolate SAI index rebuilds from ZCS (CASSANDRA-21520)
7071
* Bound and chunk the BTI partition index preload (CASSANDRA-21632)
7172
* Fix compressed scan read-ahead buffer Block leak and chunk-cache pollution by scans (CASSANDRA-21671)

‎doc/modules/cassandra/pages/managing/operating/topo_changes.adoc‎

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,41 @@ unavailable replica, set the JVM flag
5050
On 2.2+, if the bootstrap process fails, it's possible to resume
5151
bootstrap from the previous saved state by calling
5252
`nodetool bootstrap resume`. If for some reason the bootstrap hangs or
53-
stalls, it may also be resumed by simply restarting the node. In order
54-
to cleanup bootstrap state and start fresh, you may set the JVM startup
55-
flag `-Dcassandra.reset_bootstrap_progress=true`.
53+
stalls, it may also be resumed by simply restarting the node.
54+
55+
==== The `cassandra.reset_bootstrap_progress` JVM property
56+
57+
When a bootstrap finds ranges that a previous, partially successful
58+
bootstrap already marked as available, the behaviour depends on the
59+
`cassandra.reset_bootstrap_progress` JVM startup property. Leaving it
60+
unset is *not* the same as setting it to `true` or to `false`.
61+
62+
[cols=",",options="header",]
63+
|===
64+
|Value |Behaviour when previous bootstrap progress is found
65+
66+
|unset (default) | If ranges from a previous bootstrap are found,
67+
the bootstrap usually aborts with an error, so that no decision
68+
about the existing data is made on your behalf. If none are found,
69+
the bootstrap proceeds normally.
70+
71+
|`true` |Discards the recorded progress and streams all ranges again.
72+
The files already streamed are *not* deleted, so remove them before
73+
retrying or you may resurrect or duplicate data. See
74+
https://issues.apache.org/jira/browse/CASSANDRA-17679[CASSANDRA-17679].
75+
76+
|`false` |Keeps the recorded progress and streams only the ranges not
77+
already marked as available. Potentially dangerous, because the data
78+
streamed by the previous attempt may be missing or incomplete. Prefer
79+
`true` after cleaning up the old files. See
80+
https://issues.apache.org/jira/browse/CASSANDRA-17679[CASSANDRA-17679].
81+
|===
82+
83+
In some situations, a bootstrap with the property unset doesn't abort.
84+
Instead, it continues and reuses the ranges that a previous attempt
85+
already streamed, without logging that it skipped them. To avoid this,
86+
we recommend setting the property to `true` after removing the files
87+
from the previous attempt.
5688

5789
On lower versions, when the bootstrap proces fails it is recommended to
5890
wipe the node (remove all the data), and restart the bootstrap process

‎src/java/org/apache/cassandra/dht/RangeStreamer.java‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -728,15 +728,18 @@ public StreamResultFuture fetchAsync()
728728

729729
if (remaining.size() < available.full.size() + available.trans.size())
730730
{
731-
// If the operator hasn't specified what to do when we discover a previous partially successful bootstrap,
732-
// we error out and tell them to manually reconcile it. See CASSANDRA-17679.
731+
// If the operator hasn't specified what to do when we discover a previous partially successful bootstrap
732+
// (some of the ranges we are about to fetch are already marked as available), we error out and spell out
733+
// the true/false choice. See CASSANDRA-17679.
733734
if (!RESET_BOOTSTRAP_PROGRESS.isPresent())
734735
{
735736
List<FetchReplica> skipped = fetchReplicas.stream().filter(isAvailable).collect(Collectors.toList());
736-
String msg = String.format("Discovered existing bootstrap data and %s " +
737-
"is not configured; aborting bootstrap. Please clean up local files manually " +
738-
"and try again or set cassandra.reset_bootstrap_progress=true to ignore. " +
739-
"Found: %s. Fully available: %s. Transiently available: %s",
737+
String msg = String.format("Discovered existing bootstrap data (ranges already marked as available by a previous " +
738+
"bootstrap attempt) and %1$s is unset; aborting bootstrap. To start a new bootstrap and " +
739+
"re-stream all ranges, delete the data files from the previous attempt and set it to 'true'. " +
740+
"To stream only the missing ranges, set it to 'false' (potentially dangerous, as the previous " +
741+
"data may be incomplete). Set it on restart with -D%1$s=<true|false>. See CASSANDRA-17679. " +
742+
"Found: %2$s. Fully available: %3$s. Transiently available: %4$s",
740743
RESET_BOOTSTRAP_PROGRESS.getKey(), skipped, available.full, available.trans);
741744
logger.error(msg);
742745
throw new IllegalStateException(msg);

0 commit comments

Comments
 (0)