Postfix for #5385 (CORE-5101): Fix slow database restore when Classic server mode is used
CCH_flush has dbb->dbb_ast_flags & DBB_shutdown_single check to avoid PIO_flush call when a database is restoring. But a restore attachment didn't update dbb->dbb_ast_flags while setting a shutdown mode in a database header. This optimization worked fine for Super server mode because it has Garbage Collector and Cache Writer attachments which read the header and update flags in a shared dbb.
This commit surely helps the described situation. I still have some doubts though. DBB_shutdown_* flags are normally set via notify_shutdown() -> SHUT_blocking_ast() -> shutdown() call chain. It works when the database goes online due to delay == -1 (see SHUT_blocking_ast()). It usually works for the database shutdown because of notify_shutdown() being finally (after timeout) called with isc_dpb_shut_force flag. However, if the first call of notify_shutdown() returns true (which means we already have an exclusive access), then DBB_shutdown_* flags are not set properly. This is probably the original problem. So I'd suggest to review (and test) the alternative approach:
// Database is being shutdown. First notification gives shutdown type and delay in seconds.
bool exclusive = notify_shutdown(tdbb, flag, delay, guard);
bool successful = exclusive;
if (exclusive)
{
// Ensure we have the proper DBB_shutdown_* flags in place
shutdown(tdbb, flag, false);
}
else
{
// Try to get exclusive database lock periodically up to specified delay. If we
// haven't gotten it report shutdown error for weaker forms. For forced shutdown
// keep notifying until successful.
SSHORT timeout = delay ? delay - 1 : 0;
do
{
if (!(dbb->dbb_ast_flags & (DBB_shut_attach | DBB_shut_tran | DBB_shut_force)))
break;
if ((flag & isc_dpb_shut_transaction) && !TRA_active_transactions(tdbb, dbb))
{
successful = true;
break;
}
if (timeout && CCH_exclusive(tdbb, LCK_PW, -1, guard))
{
exclusive = true;
break;
}
}
while (timeout--);
}
A workaround could also be to add isc_dpb_shut_force option to gbak, but I'd rather avoid that.
However, if the first call of
notify_shutdown()returns true (which means we already have an exclusive access), thenDBB_shutdown_*flags are not set properly. This is probably the original problem. So I'd suggest to review (and test) the alternative approach
I agree, this approach is better. I've tested it and it works fine.