DB Backup - бекап базы данных из админки для Cotonti

плагин резервного копирования и восстановления базы данных для CMS Cotonti, обрабатывает большие базы данных, показывает прогресс в реальном времени

Статус: Опубликован

19

DB Backup (dbbackdump) для Cotonti

Version
Cotonti Compatibility
PHP
License

Современный плагин резервного копирования и восстановления базы данных для CMS Cotonti. Работает в один процесс, поддерживает два движка (нативный mysqldump и чистый PHP), умеет корректно обрабатывать большие базы данных, показывает прогресс в реальном времени и не роняет сайт при дампах объёмом десятки гигабайт.


📑 Оглавление


1. Общие сведения

1.1. Что такое dbbackdump

dbbackdump — это плагин для CMS Cotonti, который предоставляет администратору сайта возможность создавать, скачивать, восстанавливать и удалять резервные копии базы данных MySQL прямо из административной панели, без необходимости заходить на сервер по SSH, использовать phpMyAdmin или сторонние утилиты.

Плагин разработан как «современная замена» устаревших решений для бэкапа БД, которые:

  • грузят всю базу в память → падают на больших БД;
  • не показывают прогресс → админ не понимает, работает ли операция;
  • не дают отменить операцию → приходится ждать таймаута;
  • не поддерживают потоковое восстановление → съедают всю память при restore;
  • не умеют работать с mysqldump → медленно и неполно.

dbbackdump решает все эти проблемы.

1.2. Ключевые возможности

  • Два движка дампа:
    • native — использует системный mysqldump через proc_open() и сразу сжимает поток в gzip;
    • pure-PHP — если mysqldump недоступен, дампит таблицы курсором по PRIMARY KEY батчами по 1000 строк;
  • Потоковое восстановление — gzip читается порциями по 512 КБ, SQL-запросы разбираются «на лету» без загрузки всего дампа в память;
  • Прогресс в реальном времени — через AJAX опрос состояния .job.json;
  • Отмена операции — кнопка «Отменить» прерывает dump/restore на середине;
  • Ротация бэкапов — автоматическое удаление старых копий по настройке keep_backups;
  • Защита файлов — .htaccess + index.php создаются автоматически в папке бэкапов;
  • Безопасность — авторизация Cotonti + проверка XK-токена на каждом AJAX-запросе;
  • Логирование — все ошибки пишутся в .log внутри папки бэкапов с усечённым SQL-хвостом.

1.3. Системные требования

Компонент Минимальная версия Рекомендуемая
PHP 8.5 8.5+
MySQL 8.0 8.4+
MariaDB 10.6 11.4+
Cotonti Verona 1.0.0 Verona 1.0.0+
Расширения PHP pdo_mysql, zlib + proc_open, exec

Обязательные расширения PHP:

  • pdo_mysql — обязательно, иначе Cotonti не работает;
  • zlib — обязательно, без него не будет gzip-сжатия;
  • mbstring — для обрезки длинных SQL-ошибок в логе;
  • json — встроен в PHP ≥ 8.0.

Опциональные расширения / функции:

  • proc_open — нужен для native-режима mysqldump;
  • exec — нужен для проверки версии mysqldump;
  • ignore_user_abort — нужен для продолжения работы после закрытия вкладки.

Если proc_open/exec запрещены хостингом, плагин автоматически переключается на pure-PHP движок.

Важно: плагин использует класс Pdo\Mysql (новый API PHP 8.5). На PHP 8.4 и ниже работать не будет.

1.4. Совместимость

Плагин протестирован на:

  • Cotonti Verona 1.0.0+;
  • MySQL 8.0, 8.4;
  • MariaDB 10.6 — 11.4;
  • PHP 8.5;
  • Apache 2.4, Nginx (с php-fpm), LiteSpeed.

1.5. Лицензия

BSD 3-Clause. Полный текст — в файле License.txt.


2. Принципы работы

2.1. Общая архитектура

Плагин состоит из четырёх основных частей:

  1. Админ-страница (dbbackdump.admin.php + шаблон) — UI, кнопки, таблица бэкапов.
  2. AJAX-эндпоинт (dbbackdump.ajax.php) — обработчик всех асинхронных запросов.
  3. Библиотека функций (inc/dbbackdump.functions.php) — вся логика.
  4. Файл состояния (.job.json в папке бэкапов) — «мост» между длительным процессом и AJAX-опросом.

Ключевая идея: всё работает в одном PHP-процессе. Плагин не использует cron, очереди, форки или фоновые воркеры. Запуск дампа/восстановления происходит прямо внутри AJAX-запроса start_dump/start_restore, а прогресс пишется в файл .job.json, который параллельно читается другими AJAX-запросами status.

Это даёт:

  • простоту установки — не нужно настраивать cron или демоны;
  • переносимость — работает на любом шаред-хостинге с PHP;
  • прозрачность — легко отлаживать, все действия видны в логе.

2.2. Структура плагина

plugins/dbbackdump/
├── dbbackdump.setup.php        # регистрация плагина и его конфигурации
├── dbbackdump.admin.php        # контроллер админ-страницы
├── dbbackdump.ajax.php         # AJAX-эндпоинт
├── inc/
│   └── dbbackdump.functions.php  # ядро плагина
├── lang/
│   ├── dbbackdump.ru.lang.php    # русская локализация
│   └── dbbackdump.en.lang.php    # английская локализация
├── tpl/
│   └── dbbackdump.admin.tpl      # шаблон админ-страницы
└── README.md                     # этот файл

2.3. Два движка резервного копирования

2.3.1. Native — mysqldump

Используется если:

  • включена опция prefer_mysqldump;
  • в mysqldump_path указан существующий бинарь;
  • функция exec() разрешена на хостинге.

Алгоритм:

  1. Запускается mysqldump через proc_open() с флагами --single-transaction --quick --routines --triggers --hex-blob --default-character-set=utf8mb4.
  2. Пароль передаётся через переменную окружения MYSQL_PWD — это исключает попадание пароля в ps aux.
  3. stdout процесса читается порциями по 128 КБ.
  4. Каждая порция немедленно пишется в gzip-файл.
  5. stderr читается отдельно, после завершения процесса, и при ненулевом exit-code выбрасывается исключение.

Плюсы: скорость, поддержка routines, triggers, events, корректное экранирование.

Минусы: нужен exec и proc_open; нужен mysqldump на сервере; версия клиента должна быть ≥ версии сервера.

2.3.2. Pure-PHP — cursor по PRIMARY KEY

Используется если mysqldump недоступен.

Алгоритм:

  1. Получаем список таблиц через SHOW TABLES.
  2. Для каждой таблицы:
    • пишем DROP TABLE IF EXISTS;
    • пишем результат SHOW CREATE TABLE;
    • определяем PRIMARY KEY (SHOW KEYS FROM ... WHERE Key_name='PRIMARY');
    • читаем строки батчами по 1000 с сортировкой по PK;
    • для следующего батча используем WHERE pk > last_value — это защищает от «сдвига окна» при параллельной записи;
    • пишем INSERT INTO ... VALUES (...), (...), ...;
  3. Если у таблицы нет PRIMARY KEY — читаем всё за один SELECT, но это опасно на больших таблицах.

Плюсы: работает везде, где есть PHP; не нужен mysqldump.

Минусы: медленнее; не сохраняет triggers, events, routines; хуже для таблиц без PRIMARY KEY; для полнотекстовых таблиц с тяжёлыми данными может тормозить.

2.4. Формат файла бэкапа

Файл — это обычный gzip-сжатый SQL-дамп, совместимый с:

  • mysql < backup.sql;
  • gunzip < backup.sql.gz | mysql dbname;
  • phpMyAdmin (импорт);
  • Adminer;
  • любым другим SQL-клиентом.

Заголовок дампа:

-- Cotonti DB Backup (pure-PHP cursor)
-- 2026-10-16T12:34:56+00:00
-- DB: my_database

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET time_zone='+00:00';

Далее — таблицы, и в конце:

SET FOREIGN_KEY_CHECKS=1;

Имя файла: backup_YYYY-MM-DD_HH-II-SS.sql.gz.

2.5. Процесс создания бэкапа

  1. Админ жмёт кнопку «Создать бэкап».
  2. JS отправляет AJAX-запрос a=start_dump с XK-токеном.
  3. dbbackdump_start_dump():
    • проверяет, не идёт ли уже другой процесс (читает .job.json);
    • ставит ignore_user_abort(true), set_time_limit(0), memory_limit=1024M;
    • генерирует имя файла и открывает gzip;
    • пишет начальное состояние в .job.json (status=running);
    • выбирает движок (mysqldump или pure-PHP);
    • выполняет дамп;
    • по завершении вызывает dbbackdump_rotate() — удаляет старые копии;
    • пишет состояние done в .job.json.
  4. Параллельно JS раз в 1200 мс дёргает a=status и обновляет прогресс-бар.
  5. По завершении JS перезагружает страницу.

2.6. Процесс восстановления

Восстановление — самая сложная часть, потому что нужно:

  • не загружать весь .sql.gz в память;
  • корректно разбирать SQL с учётом кавычек, экранирования, многострочных строк и ; внутри INSERT;
  • показывать прогресс по мере чтения файла;
  • уметь прерваться по нажатию «Отменить».

Алгоритм dbbackdump_run_restore():

  1. Устанавливает FOREIGN_KEY_CHECKS=0, NAMES utf8mb4, SQL_MODE.
  2. Открывает .sql.gz через fopen('compress.zlib://...').
  3. Читает порциями по 512 КБ в буфер.
  4. Сканирует буфер посимвольно, отслеживая:
    • $inStr — внутри одинарной кавычки;
    • $inBt — внутри бэктика (имя таблицы/колонки);
    • $escape — после \;
    • '' — как экранированную кавычку внутри строки.
  5. Как только встречается ; вне строки и вне бэктика — весь текст до него считается запросом и выполняется через Cot::$db->query($sql).
  6. Выполненный префикс удаляется из буфера (substr($buffer, $i+1)), позиция $i сбрасывается в 0.
  7. Важный момент: $i не сбрасывается при чтении нового чанка — только после успешного выполнения запроса. Иначе кавычки в уже пройденной части буфера пересчитываются второй раз, $inStr залипает, ; перестаёт распознаваться и INSERT'ы молча пропускаются.
  8. Каждые 50 выполненных запросов:
    • обновляется .job.json (прогресс по ftell($fh) / filesize($path));
    • проверяется, не нажал ли админ «Отменить».
  9. По завершении — FOREIGN_KEY_CHECKS=1.

2.7. Система состояний (.job.json)

Файл .job.json в папке бэкапов — это «мост» между длительным процессом и AJAX-опросом. Структура:

{
  "status":  "running",
  "type":    "dump",
  "file":    "backup_2026-10-16_12-34-56.sql.gz",
  "percent": 42,
  "message": "Table x92374_pages (12/35)",
  "started": 1760618096,
  "finished": null,
  "error":   null
}

Возможные значения status:

Статус Что значит
running Операция выполняется прямо сейчас
done Успешно завершено
error Ошибка, в поле error — текст
cancelled Прервано пользователем
(отсутствует) Файла нет → плагин считает, что ничего не идёт

2.8. AJAX API

Все запросы идут на index.php?r=dbbackdump&a=<action>&x=<XK>.

Action Метод Параметры Возвращает
start_dump GET — {status, percent, message}
start_restore GET name=<файл> {status, percent, message}
status GET — {status, percent, message, file, error}
cancel GET — {ok: true}
download GET name=<файл> бинарный gzip

Все ответы (кроме download) — JSON вида:

{ "ok": true, "data": { ... } }

или

{ "ok": false, "error": "текст ошибки" }

2.9. Логирование

Файл .log в папке бэкапов. Формат:

2026-10-16T12:34:56+00:00 DUMP OK backup_2026-10-16_12-34-56.sql.gz
2026-10-16T12:35:10+00:00 RESTORE OK backup_2026-10-16_12-34-56.sql.gz
2026-10-16T12:36:22+00:00 SQL error: SQLSTATE[42S02]: Base table or view not found | SQL head: DROP TABLE IF EXISTS `foo`

Правило: если что-то пошло не так при восстановлении — первым делом смотрите .log.

2.10. Ротация бэкапов

После каждого успешного дампа вызывается dbbackdump_rotate(). Она читает конфиг keep_backups (по умолчанию 14) и удаляет все копии, начиная с 15-й по счёту (сортировка — по дате изменения, новые вверху).

Если keep_backups = 0 — ротация выключена, копии накапливаются.


3. Правила использования

3.1. Права доступа

Доступ к плагину имеют только администраторы Cotonti с правом plug.dbbackdump.A. Это проверяется в:

  • dbbackdump.admin.php — для страницы настроек;
  • dbbackdump.ajax.php — для всех AJAX-действий.

Не-администратор получит HTTP 403.

3.2. Ограничения

  • Один процесс одновременно. Нельзя запустить два дампа параллельно — второй запрос вернёт текущий статус первого.
  • Только MySQL / MariaDB. PostgreSQL, SQLite и др. не поддерживаются.
  • Только .sql.gz в папке бэкапов. Файлы с другим расширением не видны в списке и не удаляются.
  • Только встроенный gzip. Формат .zip, .bz2, .xz не поддерживается.
  • Нет автоматического расписания. Плагин не делает бэкапы по cron — это осознанное решение, чтобы не плодить забытые задачи. Если нужно — настраивайте внешний cron и дёргайте AJAX или CLI-скрипт.

3.3. Рекомендации по эксплуатации

  • Держите keep_backups в разумных пределах. 14 копий — оптимально для большинства сайтов.
  • Храните внешнюю копию: раз в неделю скачивайте свежий бэкап и складывайте его на отдельный носитель / в облако / на другой сервер.
  • Перед обновлением Cotonti, установкой новых плагинов или крупными изменениями — всегда делайте бэкап.
  • Восстанавливайте БД только в момент минимальной нагрузки (ночью), особенно если у вас много посетителей.
  • Периодически проверяйте .log — там могут быть «тихие» ошибки SQL.
  • Не отключайте встроенный .htaccess и не удаляйте index.php из папки бэкапов.

3.4. Что категорически нельзя делать

  • ❌ Удалять .htaccess и index.php из папки бэкапов.
  • ❌ Размещать папку бэкапов внутри public_html без защиты (deny from all).
  • ❌ Указывать backup_dir с правами 777 — только 755 (или 750, 770 в зависимости от конфигурации).
  • ❌ Запускать восстановление поверх работающего сайта — сначала включите режим обслуживания.
  • ❌ Использовать root MySQL для плагина — используйте отдельного пользователя с правами только на нужную БД.
  • ❌ Прерывать дамп через killall php-fpm или перезагрузку сервера — можно получить битый .sql.gz (правда, плагин удалит его при рестарте, но лучше не доводить).
  • ❌ Хранить бэкапы только на том же диске, где и БД — умрёт диск, умрут и данные, и бэкапы.

4. Пошаговое руководство по установке

4.1. Способ 1: через админку Cotonti

  1. Скачайте архив плагина с GitHub: dbbackdump-cotonti-x.y.z.zip.
  2. Войдите в админку Cotonti под администратором.
  3. Перейдите в Расширения → Управление плагинами (/admin.php?m=extensions).
  4. Нажмите «Установить новый плагин» или «Upload plugin».
  5. Выберите скачанный .zip и подтвердите установку.
  6. Плагин появится в списке. Если он не активирован автоматически — нажмите «Установить».
  7. Перейдите в Инструменты → DB Backup (/admin.php?m=other&p=dbbackdump).

4.2. Способ 2: вручную через FTP/SFTP

  1. Скачайте плагин с GitHub.
  2. Распакуйте архив локально.
  3. Загрузите папку dbbackdump/ в /plugins/ вашего Cotonti-сайта.
  4. Убедитесь, что структура такая:
    /plugins/dbbackdump/dbbackdump.setup.php
    /plugins/dbbackdump/dbbackdump.admin.php
    /plugins/dbbackdump/dbbackdump.ajax.php
    /plugins/dbbackdump/inc/dbbackdump.functions.php
    /plugins/dbbackdump/lang/dbbackdump.ru.lang.php
    /plugins/dbbackdump/lang/dbbackdump.en.lang.php
    /plugins/dbbackdump/tpl/dbbackdump.admin.tpl
  5. Войдите в админку Cotonti.
  6. Перейдите в Расширения → Управление плагинами.
  7. Найдите dbbackdump в списке и нажмите «Установить».
  8. Убедитесь, что плагин активен.
  9. Перейдите в Инструменты → DB Backup.

4.3. Настройка прав доступа

Плагин создаёт папку для бэкапов автоматически. По умолчанию это datas/dbbackdump относительно корня сайта. Права:

# через SSH
chmod 755 /path/to/site/datas/dbbackdump
chown www-data:www-data /path/to/site/datas/dbbackdump   # пользователь веб-сервера

Если хостинг без SSH — используйте файловый менеджер в панели управления и выставьте права 755.

Если папка не создаётся автоматически — создайте её вручную и выставьте 755.

4.4. Конфигурирование плагина

Перейдите в Расширения → Управление плагинами → dbbackdump → Настройки. Доступны 4 параметра:

Параметр Значение по умолчанию Описание
backup_dir datas/dbbackdump Папка для бэкапов (относительно корня сайта или абсолютный путь)
keep_backups 14 Сколько последних копий оставлять (0 = без ограничения)
prefer_mysqldump 1 Использовать mysqldump, если доступен
mysqldump_path /usr/bin/mysqldump Абсолютный путь к mysqldump

Пример безопасной конфигурации:

backup_dir     = /var/backups/cotonti/dbbackdump   (вне public_html!)
keep_backups   = 14
prefer_mysqldump = 1
mysqldump_path = /usr/bin/mysqldump

Если папка вне public_html — скачивание через браузер не будет работать, но сам дамп/restore будет. Тогда скачивание делайте через SSH/rsync.

4.5. Проверка работоспособности

  1. Откройте Инструменты → DB Backup.
  2. Убедитесь, что в шапке отображается:
    • Движок: mysqldump (native) — если mysqldump доступен;
    • Движок: pure-PHP (cursor) — если нет.
  3. Нажмите «Создать бэкап».
  4. Дождитесь завершения — прогресс-бар должен дойти до 100%.
  5. Проверьте папку datas/dbbackdump/ — там должен быть файл backup_*.sql.gz и файл .log.
  6. Скачайте бэкап и откройте его архиватором — внутри должен быть читаемый SQL.
  7. Удалите тестовый бэкап (или оставьте как первый рабочий).

Готово. Плагин установлен и работает.


5. Пошаговое руководство по безопасности

Безопасность резервных копий — это критическая часть. Дамп содержит всю базу: логины, пароли (в виде хешей), email, личные сообщения, IP-адреса. Утечка дампа = полный компромисс сайта.

Ниже — 10 шагов, которые нужно пройти после установки.

5.1. Шаг 1: выбор места для хранения бэкапов

Плохой вариант:

/var/www/site/public_html/datas/dbbackdump/

Если сервер вдруг отдаст файл по прямой ссылке (а он отдаст, если не сработает .htaccess), дамп скачает любой, кто знает URL.

Хороший вариант:

/var/backups/cotonti/dbbackdump/

или любая директория вне корня сайта. В настройках плагина укажите абсолютный путь:

backup_dir = /var/backups/cotonti/dbbackdump

Внимание: data/, datas/, storage/ и подобные директории часто уже находятся вне public_html — это уже хорошо. Проверьте это на своём хостинге.

5.2. Шаг 2: защита директории бэкапов

Если папка всё-таки внутри public_html — плагин автоматически создаст два файла:

  • .htaccess (для Apache):
    Require all denied
    Deny from all
    Options -Indexes
  • index.php — заглушка для директорий без index:
    <?php http_response_code(403);

Проверьте оба файла после первого запуска плагина. Если их нет — создайте вручную.

Для Nginx: .htaccess не работает. Добавьте в конфиг сервера:

location ^~ /datas/dbbackdump/ {
    deny all;
    return 403;
}

Для LiteSpeed .htaccess работает, но проверьте, что AllowOverride All включён для вашего vhost.

5.3. Шаг 3: права на файлы

chmod 755 /var/backups/cotonti/dbbackdump
chmod 640 /var/backups/cotonti/dbbackdump/*.sql.gz
chmod 640 /var/backups/cotonti/dbbackdump/.log
chmod 640 /var/backups/cotonti/dbbackdump/.job.json

Никогда не выставляйте 777 — это открывает папку для записи любому пользователю системы.

5.4. Шаг 4: защита AJAX-эндпоинта

AJAX-эндпоинт (index.php?r=dbbackdump) уже защищён:

  • проверкой авторизации (cot_auth('plug', 'dbbackdump', 'A'));
  • проверкой XK-токена (cot_check_xg()).

Что можно усилить:

  • Добавить HTTP Basic Auth на /index.php?r=dbbackdump через .htaccess (двойная защита).
  • Ограничить доступ по IP в .htaccess:
    <If "%{QUERY_STRING} =~ /r=dbbackdump/">
        Require ip 203.0.113.42
        Require ip 198.51.100.0/24
    </If>
  • Вести лог всех запросов к AJAX-эндпоинту.

5.5. Шаг 5: XK-токены и CSRF

Cotonti использует XK-токены (аналог CSRF-токенов) для всех действий, изменяющих состояние. Плагин проверяет токен на каждом AJAX-запросе через cot_check_xg().

Что это даёт: даже если злоумышленник обманом заставит админа открыть вредоносную страницу, браузер не сможет выполнить запрос без правильного XK.

Что можно улучшить:

  • Убедитесь, что Cot::$sys['xk'] не утекает в JS-консоль / сторонние скрипты.
  • Не отключайте cot_check_xg() ни при каких обстоятельствах.
  • Если вы используете CDN или сторонние виджеты — проверьте, что они не читают data-xk атрибут.

5.6. Шаг 6: отдельный пользователь MySQL

Не используйте root MySQL для сайта. Создайте отдельного пользователя:

CREATE USER 'cotonti_backup'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON `your_db`.* TO 'cotonti_backup'@'localhost';
-- Для восстановления также нужны:
GRANT INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, REFERENCES ON `your_db`.* TO 'cotonti_backup'@'localhost';
FLUSH PRIVILEGES;

Пропишите этого пользователя в конфиге Cotonti (datas/config.php → $cfg['mysqluser'], $cfg['mysqlpassword']).

Преимущество: если пароль утечёт через дамп/лог, злоумышленник не получит root-доступ.

5.7. Шаг 7: безопасность mysqldump

Плагин передаёт пароль MySQL через переменную окружения MYSQL_PWD, а не через командную строку. Это значит, что пароль не виден в ps aux.

Проверьте, что на сервере:

  • mysqldump не имеет suid-бита (ls -l $(which mysqldump) — не должно быть s в правах);
  • proc_open и exec разрешены в disable_functions (если нет — используется pure-PHP);
  • версия mysqldump ≥ версии MySQL-сервера (иначе возможны проблемы с совместимостью).

5.8. Шаг 8: HTTPS и заголовки

Плагин работает по тому же протоколу, что и админка. Обязательно используйте HTTPS:

  • без HTTPS XK-токен и содержимое дампа могут быть перехвачены;
  • куки админа передаются в открытом виде (если не установлен флаг Secure).

Убедитесь, что:

  • на сервере стоит валидный TLS-сертификат (Let's Encrypt);
  • HTTP редиректит на HTTPS;
  • куки сессии имеют флаги Secure, HttpOnly, SameSite=Lax (или Strict).

5.9. Шаг 9: регулярный аудит

Раз в месяц:

  1. Проверьте .log на ошибки и подозрительные записи.
  2. Проверьте список бэкапов — нет ли лишних файлов.
  3. Проверьте .htaccess — не изменён ли.
  4. Проверьте права на папку — не 777 ли.
  5. Проверьте, что ротация работает (старые файлы удаляются).
  6. Сделайте тестовое восстановление на отдельной копии сайта (staging).

5.10. Шаг 10: резервное копирование резервных копий

Золотое правило: 3-2-1.

  • 3 копии данных;
  • 2 разных носителя;
  • 1 копия вне офиса (вне сервера).

Минимум: раз в неделю скачивайте свежий бэкап и складывайте:

  • на локальный компьютер;
  • в облако (Яндекс.Диск, Google Drive, Dropbox, S3);
  • на резервный сервер.

Автоматизировать можно через cron:

# Каждый день в 04:00 забирать все свежие дампы
0 4 * * * rsync -avz --remove-source-files user@site:/var/backups/cotonti/dbbackdump/ /home/backup/cotonti/

6. Пошаговое руководство по использованию

6.1. Создание резервной копии

  1. Откройте Инструменты → DB Backup.
  2. Убедитесь, что ни один процесс не идёт (прогресс-бар скрыт).
  3. Нажмите «Создать бэкап».
  4. Появится прогресс-бар и кнопка «Отменить».
  5. Дождитесь завершения — статус станет done, прогресс 100%, страница перезагрузится.
  6. Новый бэкап появится в таблице сверху.

Сколько это длится? Зависит от размера БД и выбранного движка:

Размер БД mysqldump pure-PHP
10 МБ 1-2 сек 3-5 сек
100 МБ 5-15 сек 30-60 сек
1 ГБ 1-2 мин 5-15 мин
10 ГБ 10-20 мин 1-3 часа

6.2. Скачивание бэкапа

  1. Найдите нужный файл в таблице.
  2. Нажмите «Скачать» — файл начнёт скачиваться.
  3. Файл отдаётся как application/gzip с заголовком Content-Disposition: attachment.

Внимание: скачивание идёт через AJAX-эндпоинт, то есть через PHP. Это значит:

  • если у вас лимит max_execution_time = 30 и файл скачивается дольше — процесс может быть убит;
  • для больших файлов (>1 ГБ) лучше использовать SFTP/rsync.

6.3. Восстановление из бэкапа

⚠️ Восстановление полностью перезаписывает текущую БД. Все данные, появившиеся после создания бэкапа, будут потеряны.

  1. Включите режим обслуживания. В Cotonti это делается через админку (Настройки → Основные → Режим обслуживания) или вручную.
  2. Убедитесь, что у вас есть актуальный бэкап (сделан только что) — на случай, если восстановление пойдёт не так.
  3. Откройте Инструменты → DB Backup.
  4. Найдите в таблице нужный бэкап.
  5. Нажмите «Восстановить».
  6. Подтвердите действие в диалоге.
  7. Дождитесь завершения прогресса — статус станет done.
  8. Проверьте .log на ошибки SQL.
  9. Зайдите на сайт, проверьте ключевые страницы.
  10. Выключите режим обслуживания.

Если восстановление упало на середине: часть таблиц уже перезаписана, часть нет. Единственный способ гарантированно починить — снова запустить восстановление из того же бэкапа. Не пытайтесь «доделать руками» — почти всегда получите несогласованные данные.

6.4. Удаление бэкапа

  1. Найдите файл в таблице.
  2. Нажмите «Удалить».
  3. Подтвердите действие.
  4. Страница перезагрузится, файл исчезнет из списка.

Внимание: удаление необратимо. Файл физически стирается с диска.

6.5. Отмена операции

  1. Если операция выполняется — доступна кнопка «Отменить».
  2. Нажмите её.
  3. Плагин установит статус cancelled в .job.json.
  4. Процесс дампа/restore увидит это при следующей проверке (каждые 50 запросов при restore, раз в таблицу при dump) и прервётся.
  5. Файл бэкапа (при dump) будет удалён.

Внимание: отмена — это не мгновенный процесс. При restore может пройти несколько секунд, пока текущий батч запросов не завершится. При dump на больших таблицах — тоже.


7. Возможные проблемы и их решения

7.1. Плагин не создаёт директорию для бэкапов

Симптом: ошибка «Cannot create /path/to/datas/dbbackdump».

Причины и решения:

  1. Нет прав на родительскую директорию.

    chmod 755 /path/to/datas

    Или укажите backup_dir в существующую директорию, куда есть права на запись.

  2. Директория вне открытых путей open_basedir.
    Проверьте phpinfo() → open_basedir. Если путь не входит — укажите backup_dir внутри разрешённой зоны.

  3. Диск заполнен.

    df -h

    Освободите место или перенесите папку.

  4. SELinux / AppArmor блокирует запись.

    sudo restorecon -Rv /var/backups/cotonti/

    Или настройте политику.

7.2. mysqldump не найден

Симптом: в шапке отображается pure-PHP (cursor), хотя prefer_mysqldump = 1.

Причины и решения:

  1. Неверный путь к mysqldump.

    which mysqldump
    # /usr/bin/mysqldump

    Пропишите этот путь в настройках.

  2. exec() в disable_functions.
    Проверьте phpinfo() → disable_functions. Если exec или proc_open там есть — используйте pure-PHP (просто отключите prefer_mysqldump).

  3. mysqldump не установлен.

    sudo apt install mysql-client       # Debian/Ubuntu
    sudo yum install mysql              # CentOS/RHEL
  4. Нет прав на выполнение.

    ls -l $(which mysqldump)   # должно быть -rwxr-xr-x

7.3. Таймаут и обрыв соединения

Симптом: процесс начинается, но через 30-60 секунд падает с ошибкой 504 Gateway Timeout или 500.

Причины и решения:

  1. max_execution_time.
    Плагин вызывает set_time_limit(0), но на некоторых хостингах это запрещено. Проверьте:

    php -i | grep max_execution_time

    Если стоит 30 и не переопределяется — обратитесь в поддержку хостинга.

  2. Nginx fastcgi_read_timeout.

    fastcgi_read_timeout 3600s;
    fastcgi_send_timeout 3600s;

    Перезагрузите nginx: sudo systemctl reload nginx.

  3. Apache TimeOut.

    TimeOut 3600

    Или через .htaccess:

    <IfModule mod_reqtimeout.c>
        RequestReadTimeout header=0 body=0
    </IfModule>
  4. Cloudflare / CDN.
    Cloudflare по умолчанию режет запросы >100 секунд. Включите «Bypass Cache» для URL index.php?r=dbbackdump* или отключите проксирование для админки.

  5. Балансировщик нагрузки.
    Если сайт за LB — увеличьте idle timeout до 1 часа.

7.4. Большие базы данных

Симптом: дамп большой БД (>5 ГБ) падает, gzip-файл битый.

Решения:

  1. Используйте mysqldump. Pure-PHP для 10+ ГБ — это часы работы. С mysqldump — минуты.
  2. Разбейте таблицы. Если есть гигантские таблицы (логи, кеш) — исключите их из дампа или дампите отдельно.
  3. Увеличьте memory_limit.
    memory_limit = 2048M
  4. Проверьте tmpdir. При работе с большими таблицами MySQL может писать во временные файлы. Убедитесь, что места хватает:
    df -h /tmp

7.5. Ошибка 500 при дампе

Симптом: AJAX-запрос падает с HTTP 500, ничего не пишется в .log.

Причины и решения:

  1. Фатальная ошибка PHP. Смотрите error_log PHP:

    tail -f /var/log/php/error.log

    Или в панели хостинга.

  2. Превышен memory_limit. Увеличьте до 512-1024 МБ.

  3. proc_open не разрешён. Отключите prefer_mysqldump.

  4. Ошибка парсинга SQL в pure-PHP. Проверьте, что версия PHP ≥ 8.5.

7.6. Не восстанавливаются таблицы

Симптом: прогресс доходит до 100%, но данные не появились. В .log — ничего.

Причина: это была классическая проблема со сбросом $i в старых версиях плагина. Если у вас версия < 3.0.1 — обновитесь.

Проверка: в логе должно быть RESTORE OK. Если его нет — процесс упал молча, ищите причину в error_log PHP.

Если версия ≥ 3.0.1 и всё равно не работает:

  1. Проверьте, что SQL-дамп валиден. Распакуйте gzip и посмотрите глазами:
    gunzip -c backup_*.sql.gz | head -100
  2. Проверьте, что в дампе есть нужные таблицы:
    gunzip -c backup_*.sql.gz | grep -c "^INSERT INTO"
  3. Проверьте .log на конкретные ошибки SQL. Если есть SQL error — плагин «проглотил» проблемный запрос. Найдите его по SQL head: и разберитесь вручную.

7.7. Memory limit exceeded

Симптом: Allowed memory size of XXX bytes exhausted.

Решения:

  1. Увеличьте memory_limit до 1024 МБ.
  2. Плагин уже ставит ini_set('memory_limit', '1024M'), но если хостинг блокирует ini_set — не поможет. Тогда используйте pure-PHP (не mysqldump) или разбейте БД.

7.8. Кракозябры вместо кириллицы

Симптом: после восстановления вместо русских букв — ???? или Привет.

Причины и решения:

  1. Дамп в другой кодировке. Проверьте заголовок дампа:

    gunzip -c backup_*.sql.gz | head -5

    Должно быть SET NAMES utf8mb4;.

  2. База не в utf8mb4. Проверьте:

    SHOW CREATE DATABASE my_db;

    Если кодировка не utf8mb4 — плагин не виноват, проблема в исходной БД.

  3. Соединение не в utf8mb4. Проверьте datas/config.php → $cfg['mysqlcharset'].

7.9. Прерванный дамп остался висеть

Симптом: .job.json содержит status=running, но никакой процесс не идёт. Кнопки «Создать бэкап» — disabled.

Решение: удалите .job.json вручную:

rm /path/to/backups/.job.json

Внимание: перед удалением убедитесь, что процесс точно не идёт (ps aux | grep php). Иначе вы удалите «мост» между процессом и UI, но процесс продолжит работу.

7.10. Прогресс-бар не двигается

Симптом: прогресс-бар застыл на 0% или на N%, не двигается.

Причины и решения:

  1. setInterval в JS остановился. Проверьте консоль браузера на ошибки.
  2. AJAX-запрос status возвращает 403 или 500. Проверьте Network в DevTools.
  3. XK-токен истёк. Перезагрузите страницу.
  4. Файл .job.json не пишется. Проверьте права на папку бэкапов (755) и на сам файл (640).
  5. Долгая таблица. На больших таблицах прогресс может стоять минутами. Просто подождите.

8. Логи и диагностика

8.1. Где смотреть

Что Где
Лог плагина datas/dbbackdump/.log
Текущее состояние datas/dbbackdump/.job.json
PHP-ошибки /var/log/php/error.log, error_log сайта
Ошибки MySQL /var/log/mysql/error.log
Ошибки Apache /var/log/apache2/error.log
Ошибки Nginx /var/log/nginx/error.log

8.2. Что смотреть в первую очередь

  1. .job.json — какой статус.
  2. .log — есть ли SQL error, DUMP FAIL, RESTORE FAIL.
  3. DevTools → Network — какие AJAX-запросы идут, что возвращают.
  4. DevTools → Console — есть ли JS-ошибки.
  5. error_log PHP — есть ли fatal errors.

8.3. Включение подробного логирования

Cotonti умеет логировать SQL-запросы в режиме разработки. В datas/config.php:

$cfg['debug_mode'] = true;
$cfg['devmode'] = true;

После этого все запросы плагина (включая restore) будут видны в дебаг-панели Cotonti с временем выполнения и stack trace.

Внимание: не оставляйте эти флаги включёнными на production.


9. FAQ — часто задаваемые вопросы

Общее

Q: Плагин делает бэкап по расписанию?

A: Нет. Расписание — это задача cron, а не плагина. Настройте внешний cron, который будет дёргать AJAX-эндпоинт start_dump с валидным XK.

Q: Плагин умеет бэкапить файлы (картинки, вложения)?

A: Нет. Только БД. Для файлов используйте tar/rsync.

Q: Плагин работает с PostgreSQL?

A: Нет. Только MySQL и MariaDB.

Q: Плагин работает на Cotonti Verona?

A: Да, начиная с версии 3.0.0. Плагин рассчитан на Cotonti Verona 1.0.x (PHP 8.5).

Q: Что делать, если хостинг запрещает proc_open?

A: Плагин автоматически переключится на pure-PHP движок. Просто убедитесь, что prefer_mysqldump не мешает.

Q: Можно ли восстановить отдельную таблицу?

A: Штатно — нет. Но можно распаковать .sql.gz и вырезать нужный INSERT INTO, затем выполнить вручную через phpMyAdmin.

Безопасность

Q: Дампы доступны из браузера по прямой ссылке?

A: Нет, если .htaccess или конфиг Nginx корректны. Проверьте вручную.

Q: Что если .htaccess не работает (Nginx)?

A: Добавьте location ^~ /путь/к/бэкапам/ { deny all; } в конфиг Nginx.

Q: Пароль MySQL попадает в логи?

A: Нет, плагин передаёт пароль через MYSQL_PWD, а не через аргументы командной строки.

Q: Нужен ли HTTPS?

A: Обязательно. Без HTTPS XK-токен и содержимое дампа могут быть перехвачены.

Q: Можно ли давать доступ к плагину не-админам?

A: Нет. Только админы с правом plug.dbbackdump.A.

Использование

Q: Сколько времени занимает создание бэкапа?

A: Зависит от размера БД и движка. См. таблицу в разделе 6.1.

Q: Можно ли запустить два дампа одновременно?

A: Нет. Второй запрос вернёт статус первого.

Q: Что делать, если дамп упал на середине?

A: Проверьте .log и error_log PHP. Обычно это memory_limit, max_execution_time или ошибка SQL.

Q: Что делать, если restore упал на середине?

A: Запустите снова. Не пытайтесь «доделать руками».

Q: Как отменить операцию?

A: Кнопка «Отменить» в UI. Отмена срабатывает не мгновенно.

Q: Где хранятся бэкапы?

A: В папке, указанной в backup_dir. По умолчанию datas/dbbackdump.

Q: Как изменить папку бэкапов?

A: В настройках плагина.

Q: Как изменить количество хранимых копий?

A: Параметр keep_backups.

Q: Как отключить ротацию?

A: Поставить keep_backups = 0.

Проблемы

Q: Плагин не видит старые бэкапы.

A: Проверьте расширение файла — только .sql.gz. Проверьте права на чтение.

Q: Прогресс-бар не двигается.

A: Проверьте Network в DevTools. Возможно, истёк XK-токен — перезагрузите страницу.

Q: Ошибка «Call to undefined method CotDB::exec()».

A: Это баг старых версий плагина. Обновитесь до 3.0.1+. В новых версиях везде используется CotDB::query().

Q: Восстановление прошло, но данные не появились.

A: Проверьте .log на SQL error. Скорее всего, один из запросов упал. Найдите по SQL head: и разберитесь вручную.

Q: Кракозябры после восстановления.

A: Проверьте кодировку БД и соединения (utf8mb4).

Q: Долго восстанавливается большая таблица.

A: Нормально. Pure-PHP восстановление 10+ ГБ может занимать часы. Используйте mysqldump для дампа и mysql < backup.sql через SSH для восстановления.


10. Обновление плагина

  1. Сделайте бэкап БД штатным способом.
  2. Скачайте новую версию с GitHub.
  3. В админке Cotonti → Расширения → dbbackdump → «Обновить».
  4. Если обновление через админку недоступно — распакуйте поверх старой папки, сохранив datas/dbbackdump/ с бэкапами.
  5. Проверьте настройки плагина — иногда добавляются новые параметры.
  6. Сделайте тестовый дамп для проверки.

11. Удаление плагина

  1. Сделайте финальный бэкап БД.
  2. Скачайте все нужные бэкапы из папки datas/dbbackdump/ — при удалении плагина они не удаляются, но лучше перестраховаться.
  3. В админке Cotonti → Расширения → dbbackdump → «Удалить».
  4. Удалите папку /plugins/dbbackdump/ вручную, если она осталась.
  5. Удалите папку datas/dbbackdump/ вручную, если она не нужна.

12. Дорожная карта

  • [ ] CLI-режим для запуска из cron без HTTP.
  • [ ] Хранение бэкапов в S3-совместимых хранилищах.
  • [ ] Шифрование дампов на лету (age, gpg).
  • [ ] Поддержка PostgreSQL.
  • [ ] Выборочное восстановление отдельных таблиц.
  • [ ] Дифференциальные дампы.
  • [ ] Веб-интерфейс для просмотра .log.
  • [ ] Уведомления по email после завершения дампа.

13. История изменений

v3.0.1 (2026-10-16)

  • Исправлен баг с парсером SQL в dbbackdump_run_restore(): сброс $i внутри цикла fread приводил к молчаливому пропуску INSERT'ов.
  • Улучшено логирование ошибок SQL — теперь пишется SQL head (первые 300 символов проблемного запроса).
  • Верстка админки переведена на Bootstrap 5.3.
  • Все хардкодные русские строки вынесены в .lang.php.
  • Исправлены устаревшие требования: PHP 8.5, Cotonti Verona 1.0.x.

v3.0.0 (2026-10-01)

  • Полностью переписан с нуля.
  • Два движка: mysqldump и pure-PHP cursor.
  • Потоковое восстановление без загрузки в память.
  • Прогресс в реальном времени через AJAX.
  • Отмена операций.
  • Автоматическая защита папки бэкапов.

14. Участие в разработке

Pull-request'ы приветствуются. Перед отправкой:

  1. Форкните репозиторий.
  2. Создайте ветку feature/your-feature или fix/your-bug.
  3. Следуйте PSR-12.
  4. Добавьте тесты, если возможно.
  5. Обновите README.md и CHANGELOG.
  6. Отправьте PR с описанием: что, зачем, как проверить.

15. Лицензия

BSD 3-Clause. См. License.txt.


16. Контакты и поддержка

Купить DB Backup - бекап базы данных из админки для Cotonti по низким ценам. Интернет-магазин предлагает заказать DB Backup - бекап базы данных из админки для Cotonti, просмотреть полное описание, детальные характеристики, фото товара и актуальные цены со скидками
С этим товаром, люди часто заказывают: Установка, интеграция и адаптация плагинов под Cotonti CMF.


Рейтинг на основе отзывов:
Звезд получено: 0
Oтзывов всего: 0
Средняя оценка: 0
13 минут чтения
Владелец: Administrator

You may have been looking for this for a long time.:

Модуль Market PRO v.5+ для Cotonti CMF.

Administrator
Продавец товара: Administrator
Витрина продавца

Оффлайн

Последняя авторизация: 18.10.2026 19:33

Публичный профиль
  • Дата размещения 18.10.2026 13:24
  • Обновлено 18.10.2026 19:02

Витрина Market PRO

CMS, Скрипт и Движок - веб сайта онлайн-витрины, интернет магазина инфопродуктов и цифровых товаров. Разные цены в разных валютах на товар. Онлайн-оплата в криптовалюте за товары и услуги.