Clouds 26.150.0: таймаут -1 в блокировке загрузки заменили на миллион секунд ради MariaDB 11.4
В clouds 26.150.0 одна правка в CCloudStorageUpload, три строки кода с комментарием про MariaDB 11.4. На MariaDB 11.4 и новее блокировка прогресса multipart-загрузки в облако с таймаутом -1 штатно не берётся, теперь таймаут положительный. API и схема БД не менялись.
Обновитесь, если база на MariaDB 11.4+
Блокировку прогресса multipart-загрузки CCloudStorageUpload брал так: $connection->lock($lockId, -1). Минус единица означала «ждать сколько угодно». В новом коде рядом с константой написано, почему так больше нельзя:
// Negative GET_LOCK timeouts are rejected since MariaDB 11.4, so wait "forever" is a large positive value.
private const PROGRESS_LOCK_TIMEOUT = 1000000;
Теперь оба вызова выглядят как $connection->lock($lockId, self::PROGRESS_LOCK_TIMEOUT). Миллион секунд — это примерно 11,6 суток. На практике то же бесконечное ожидание, только положительным числом, которое база принимает.
Правка сидит в двух местах:
setParts(): метод под блокировкой записывает вb_clouds_file_uploadкарту «номер части → ETag», собранную клиентом, а при неудачной блокировке возвращаетfalse;UpdateProgress(), веткаif ($bSuccess): при неудачной блокировке сбрасывает_cacheи тоже возвращаетfalse.
До 26.100.0 UpdateProgress() результат lock() игнорировал и обновлял прогресс в любом случае. С 26.100.0 результат проверяется (новый setParts() сразу написан с проверкой), и при отказе оба метода возвращают false. Если же GET_LOCK(…, -1) на MariaDB 11.4+ падает с ошибкой запроса, загрузка ломалась и на версиях до 26.100.0. В main lock() выполняет GET_LOCK через query(), а тот при ошибке SQL бросает SqlQueryException (по коду main в эталоне). Неизвестно одно: отвечает ли MariaDB 11.4 на -1 ошибкой или возвращает NULL, от этого и зависит, какой вариант срабатывает.
Проверьте свои блокировки с -1
Если в своём коде вы тоже ждёте блокировку через Application::getConnection()->lock() с отрицательным таймаутом, на MariaDB 11.4+ вы упрётесь в то же самое. Свой код можно поправить так:
<?php declare(strict_types=1);
namespace Vendor\Sync\Service;
use Bitrix\Main\Application;
use Bitrix\Main\Error;
use Bitrix\Main\Result;
final class ExportLock
{
// «ждать сколько угодно», но положительным числом: MariaDB 11.4+ отклоняет отрицательный таймаут
private const TIMEOUT = 1_000_000;
public function run(string $name, callable $job): Result
{
$result = new Result();
$connection = Application::getConnection();
if (!$connection->lock($name, self::TIMEOUT)) {
$result->addError(new Error('Lock is busy', 'LOCK_BUSY'));
return $result;
}
try {
$job();
} finally {
$connection->unlock($name);
}
return $result;
}
}
Мелочи и находки
- Константа
PROGRESS_LOCK_TIMEOUTприватная, снаружи её не переиспользовать. - В
install/version.phpзаодно убрали висячую запятую послеVERSION_DATE, а перед первымlock()исчезла пустая строка. - Сборка датирована 17 сентября 2026, на наш эталон встала 25-го. Прошлый релиз 26.100.0 собран 23 июня, между ними почти три месяца.
- Deprecated, новых API и изменений в БД нет.
Что делать
- Портал с облачным хранилищем на MariaDB 11.4+: ставьте 26.150.0 и проверьте загрузку файла в облако.
- Поищите в своих модулях
->lock(с отрицательным таймаутом и замените его на большое положительное число.