Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,18 @@ static Connection getConnection(String connectionString, final int waitTime) thr
return con;
}
}
Connection conNew = null;
try {
final Connection conNew = DriverManager.getConnection(connectionString);
conNew = DriverManager.getConnection(connectionString);
conNew.setAutoCommit(false);
conNew.setTransactionIsolation(TRANSACTION_READ_COMMITTED);
return new CachedConnection(connectionString, conNew);
} catch (SQLException e) { // max_connection server error: try recursion for reuse connection
if (conNew != null) { // the connection was established but not set up: nothing else would close it
try {
conNew.close();
} catch (SQLException e2) {}
}
return getConnection(connectionString, (waitTime == 0) ? 1 : waitTime * 2);
}
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,33 @@ private OnDiskMergeImporter(String phase2ThreadNameTemplate, AbstractTwoPhaseImp
}

private void doImport(final Source source) throws InterruptedException, ExecutionException
{
try
{
importAllEntries(source);
}
catch (Throwable t)
{
// Cancellation lands here as well (see the InterruptedException below). The trees hold an
// incomplete import: the storage must not treat what is in them as the final data. Errors
// are caught too - an import killed by an OutOfMemoryError leaves the trees just as partial
// as one killed by an exception.
try
{
importStrategy.aborted();
}
catch (Throwable notified)
{
// What went wrong here matters less than what brought the import down: the report of the
// failure is the point of this block. Concrete for the motivating case, an import killed
// by an OutOfMemoryError, where notifying the storage allocates.
t.addSuppressed(notified);
}
throw t;
}
}

private void importAllEntries(final Source source) throws InterruptedException, ExecutionException
{
final long phaseOneStartTime = System.currentTimeMillis();
final PhaseOneWriteableTransaction transaction = new PhaseOneWriteableTransaction(importStrategy);
Expand Down Expand Up @@ -1327,6 +1354,12 @@ void afterPhaseOne()
closeSilently(bufferPool);
}

/** Tells the storage that the import stopped before it was through, so that its data is not final. */
void aborted()
{
importer.aborted();
}

abstract Callable<Void> newPhaseTwoTask(TreeName treeName, Chunk source, PhaseTwoProgressReporter progressReporter);

void afterPhaseTwo(EntryContainer entryContainer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* information: "Portions Copyright [year] [name of copyright owner]".
*
* Copyright 2015 ForgeRock AS.
* Portions Copyright 2026 3A Systems, LLC.
*/
package org.opends.server.backends.pluggable;

Expand Down Expand Up @@ -226,6 +227,14 @@ public ByteString read(TreeName name, ByteSequence key)
return value;
}

@Override
public void aborted()
{
traceEnter("aborted");
importer.aborted();
traceLeave("aborted");
}

@Override
public void close()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* information: "Portions Copyright [year] [name of copyright owner]".
*
* Copyright 2014-2016 ForgeRock AS.
* Portions Copyright 2026 3A Systems, LLC.
*/
package org.opends.server.backends.pluggable.spi;

Expand Down Expand Up @@ -74,6 +75,17 @@ public interface Importer extends Closeable
*/
SequentialCursor<ByteString, ByteString> openCursor(TreeName treeName);

/**
* Notifies this importer that the import failed or was cancelled, before {@link #close()} runs: what the trees hold
* is an incomplete import that is going to be run again. Implementations doing work of their own in {@link #close()}
* on the assumption that the data is final - refreshing the optimizer statistics of a database, for instance - can
* skip it. The default implementation does nothing.
*/
default void aborted()
{
// nothing by default: an importer that treats a partial import like a complete one is not wrong, only wasteful
}

@Override
void close();
}
Expand Down
Loading
Loading