Drupal 7 на SQLite. Некоторые тесты и миграция с SQLite на MySQL и обратно

Drupal 7 «из коробки» поддерживает сразу несколько хранилищ, а именно: СУБД MySQL, PostgreSQL, SQLite. Это значит, что уровень абстракции существующий в API Drupal`а, гарантирует, что одни и те же модули (и сайты в целом) будут с одинаковым успехом работать на любой из этих баз данных. Есть, впрочем, модули пользующиеся специфическими возможностями конкретных СУБД, например, модуль Similar Entries, предназначенный для выборки похожих материалов, устанавливает эту самую похожесть с помощью MySQL FULLTEXT (и, значит, на другой СУБД такой модуль не заведётся). Но такие монстры как Views написаны в соответствии с API, поэтому прекрасно себя чувствуют на любых хранилищах.

Кроме PostgreSQL, MySQL, SQLite поддержка других хранилищ возможна на уровне дополнительных модулей (драйверов). Например, модуль sqlsrv дружит Drupal с Microsoft SQL Server 2008+ и с облачным SQL Azure. Кстати, разработку этого драйвера спонсировала известная в Drupal-тусовке контора Commerce Guys (главный контрибьютор модуля Commerce). Есть разные решения для поддержки NoSQL-хранилищ (например, модуль для выноса в MongoDB кеша, сессий, блоков и пр.), но совсем без реляционного SQL`а наш Drupal не запустится (а надо ли?).

SQLite

Однако вернёмся к тому, что «из коробки» нам (кроме поддержки классической для LAMP-платформы MySQL-базы) достался ещё и встроенный в Drupal драйвер SQLite. Уверен, что про SQLite вы слышите не впервые, но Капитан Очевидность просил напомнить, что SQLite — это лёгкая встраиваемая реляционная база данных. Встраиваемость проявляется в том, что для SQLite не нужен постоянно работающий демон (она вообще не умеет быть клиент-серверной). Вся база — это, по сути, один бинарный файл. Для работы с этим файлом через SQL-запросы существуют биндинги и библиотеки для всего подряд, в том числе, конечно, и для PHP (но, кстати, SQLite используется и как одно из дефолтных хранилищ в Ruby On Rails). По понятным причинам SQLite обожают разработчики десктопных приложений (её удивительно легко интегрировать). Спонсируют разработку SQLite крутые ребята, например Mozilla (и не только спонсирует, но и использует в Firefox), Adobe и… Oracle.

В некоторых очень специфичных условиях (типа 25000 INSERT`ов в индексируемую таблицу на слабом процессоре с гигабайтом памяти) SQLite умудряется рвать с разницей в несколько секунд MySQL и PostgreSQL. Но с реальными приложениями, к коим разумеется относится и CMS Drupal, SQLite работает конечно медленнее, чем старшие клиент-серверные продукты.

У меня на реальных тестах получилось, что MySQL в среднем на четверть быстрее, чем SQLite. Проверял я, по сути, только SELECT`ы (генерацию страниц), но могу только подтвердить тенденцию: чем больше запросов делает страница, тем меньше оказывается разница между SQLite и MySQL. Я в проекте нашёл страницу с маркетинговыми отчётами, которая генерится 10 секунд (на странице представлен дичайшаий коктейль из вьюх), и вот на такой странице отрыв MySQL уже не столь впечатляющий, как на типовых нодах с несколькими блоками.

Сравнение производительности SQLite и MySQL

Этот результат получен под Apache на сервере с 4 гигабайтами памяти и двумя ядрами. Но если верить авторам SQLite, то чем слабее будет машина и безумнее количество запросов, тем меньше будет отставать их продукт.

Я для себя решил примерно следующее: производительности SQLite для проектов с парой сотен хостов в сутки — вполне достаточно, при условии, что сайт предназначен для просмотра анонимными пользователями.

Миграция между SQLite и MySQL

В одном из предыдущих постов я уже рассказывал о том, как у некоторых хостеров в 2012-м году отсутствует PDO, в результате чего к MySQL седьмым Drupal`ом — не подключиться. Это не единственный (и не самый благородный) повод для того, чтобы использовать SQLite. Но, в общем, ситуации бывают разные.

Я же, пользуясь случаем, торжественно подтверждаю, что Drupal в связке с SQLite дееспособен даже на живых (пускай и не нагруженных) проектах.

При этом я уверен, что вряд ли есть хоть одна команда разработчиков, в которой SQLite был бы основным и единственным движком БД как на этапе разработки и тестирования сайта, так и на боевом хосте. А, значит, любому, кто столкнётся с SQLite под Drupal`ом придётся как-то решать вопрос миграции между базами.

Есть универсальные конвертеры, позволяющие дамп MySQL превратить в .sqlite-файл (и, наверное, есть что-то и для обратной операции), но они у меня как-то не прижились, зато оказалось, что для Drupal 7 существует модуль DBTNG Migrator, позволяющий прямо из администраторской панели Drupal`а переносить данные из одного хранилища (любого поддерживаемого типа) в другое.

Соответственно, миграция боевого проекта с MySQL на SQLite и обратно — мной была опробована лично. Всё работает. Притом возможен переезд на лету, без остановки сайта.

Однако для того, чтоб модуль получил доступ к двум (или более) хранилищам, их все надо описать в конфигурационном файле ./sites/default/settings.php (привожу вариант по умолчанию, если у вас вдруг мультисайтинговая конфигурация, то разберетесь сами какой файл исправить).

Параметры базы задаются в трёхмерном массиве $databases, у вас там будет скорее всего единственный элемент второго уровня $databases['default']['default']. А наша цель состоит в том, чтоб добавить дополнительное хранилище. У меня в примере вторая база имеет ключ 'dest' и является как раз MySQL хранилищем, в отличии от основной текущей 'default' базы, которая на SQLite:

$databases = array (
        'default' => array (
                'default' => array (
                        'database' => 'sites/default/files/db.sqlite',
                        'driver' => 'sqlite', 
                        'prefix' => '',
                ),
        ),
        'dest' => array (
                'default' => array (
                        'database' => 'hti',
                        'username' => 'htiuser',
                        'password' => '**********',
                        'host' => 'localhost',
                        'port' =>'',
                        'driver' => 'mysql',
                        'prefix' =>'',
                ),
        ),
);

Нужно привести конфиг в аналогичный вид, прежде чем начинать миграцию. Кстати, вы можете предоставить вашей инсталляции Drupal`а доступ хоть к десяти хранилищам сразу, но, по умолчанию, он будет искать данные в 'default'. Зато все эти базы станут видны модулю Migrator.

Собственно, устанавливается он как и любой другой модуль, после чего становится доступным в админке:

DBTNG Migrator — модуль для миграции с MySQL на SQLite для Drupal 7

На страничке конфигурации модуля отображаются все подключенные базы, а, главное, предлагается выбрать какая из них станет источником (origin), а какая целью (destination) для переноса:

Миграция баз данных в Drupal 7 между хранилищами

После того, как в двух выпадающих списках вы правильно выберете базы, можно смело нажимать кнопку Migrate. А потом редактировать файл settings.php, чтобы в нём новая база (куда мигрировали) стала 'default'.

У модуля есть ещё режим проверки (check) на дополнительной вкладке, но он у меня работал странно: показывал ошибки, притом, что при запуске Migrate всё переносилось корректно.

В общем, SQLite совсем не страшен и вполне себе применим для скромных боевых проектов, особенно с учётом описанной выше удобной миграции между SQLite и MySQL в любом направлении.

13 комментариев

  1. Vovu4a
    Сен 24, 2012 @ 16:29:39

    Чувак, ОГРОМНОЕ ПРИОГРОМНОЕ тебе спасибо, давно искал!

    Reply

    • kostin
      Сен 24, 2012 @ 22:41:37

      Эм, искал что? Модуль для миграции?

      А вообще, конечно, пожалуйста 🙂

      Reply

  2. kadabrus
    Окт 28, 2012 @ 12:41:18

    На мой взгляд SQLite оптимален для хранения небольших объёмов данных, особенно если их надо просто и легко перемещать с места на место. Не стоит забывать и об ограничениях по количеству запросов к таким БД как MySQL и иже у большинства провайдеров на том же виртуальном хостинге. Лично я использовал SQLite под динамические данные, что в значительной степени условно снижало нагрузку на сервер. Единственно, что для меня остаётся проблемой — защита БД на SQLite. Можно конечно в папку закрытую поместить… в общем, применение SQLite имеет свои нюансы имхо 🙂

    Reply

  3. Гриша
    Янв 13, 2014 @ 13:47:21

    Спасибо огромное за гайд! Вы спасли мой сайт :). Запустил его на sqlite, но потом сайт слишком вырос и стал дико тормозить.

    Reply

  4. Vlad
    Мар 14, 2015 @ 23:51:04

    Не подскажите, как перенести сайт на другой хостинг с sqlite? Я полностью все сайты перекинул, но вылезает ошибка:

    «PDOException: SQLSTATE[HY000]: General error: 11 database disk image is malformed: SELECT expire, value FROM {semaphore} WHERE name = :name; Array ( [:name] => variable_init ) in lock_may_be_available() (line 167»

    Reply

  5. Vlad
    Мар 14, 2015 @ 23:51:39

    Имел ввиду все файлы

    Reply

  6. Макс
    Июл 22, 2015 @ 18:39:40

    столкнулся со следующей ошибкой при миграции: block already exists in destination database. DBTNG Migrator will not override existing data. Что делать ? )

    Reply

    • kostin
      Июл 22, 2015 @ 18:50:15

      А у вас целевая база (та, куда будете копировать) точно-точно пустая?

      Reply

      • Макс
        Июл 27, 2015 @ 05:35:20

        Была пустая , вылазила ошибка другая , что то вроде таблица не существует … удалил settings.php c сервера установил друпал уже с базой мускуля , включил все модули , что бы создать таблицы … потом вернул старый settings. И получил вот эту ошибку. Т.е. не ясен сам момент , нужны таблицы без данных (база с пустыми таблицами). В общем пока оставил на sqlite , cайт визитка , 50-55 страничек обычных, которые не меняются. Но хотелось бы иметь базу MySQL на всякий пожарный, или на случай переезда

        Reply

        • kostin
          Июл 27, 2015 @ 10:39:59

          ОК, значит надо создать новую пустую (без структуры таблиц и без данных) базу в мускуле, взять текущий (рабочий) settings.php и дописать в него кроме default базы (которая сейчас у тебя на sqlite) ещё и dest (см. пост) с реквизитами новой пустой базы в mysql. После этого модуль должен заработать.

          Из твоего описания получается, что коли сначала в базу мускула был установлен Друпал, то она была НЕ пустая.

          Reply

          • Макс
            Июл 27, 2015 @ 11:15:44

            так и делал сразу , выходила ошибка , как у Влада выше в комментариях. PDO******: SQL**** , ну сейчас попробую создать новую базу , и ее подключить

            Reply

          • Макс
            Июл 27, 2015 @ 20:16:49

            В общем если база пустая то выводит такую ошибку SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘cbd4.locales_source’ doesn’t exist

            Reply

Leave a Reply

*