RE:NODE

Базы данных11 мин чтения

Хостинг SQL Server Express: ограничения и когда его хватает

Что умеет и чего не умеет SQL Server 2022 Express: предел 10 GB на базу, ограничения памяти и CPU, отсутствие Agent и момент, когда пора переходить выше.

0 прочтений

SQL Server Express - бесплатная редакция Microsoft SQL Server, лицензированная для продакшена, и это тот же движок базы данных, что и в платных редакциях, только с несколькими жёсткими потолками. В SQL Server 2022 эти потолки такие: 10 GB данных на базу, около 1.4 GB памяти под buffer pool, меньшее из одного сокета или четырёх ядер и никакого SQL Server Agent. Для типичного веб-приложения, внутреннего инструмента, игрового бэкенда или небольшого SaaS этого достаточно - часто на годы. Достаточно быть перестаёт, когда одна база подходит к 10 GB, когда рабочий набор данных больше не помещается в 1.4 GB кэша или когда внутри движка нужны задачи по расписанию, репликация или высокая доступность. Эта статья проходит каждое ограничение: что происходит, когда вы в него упираетесь, как за ним следить и в какой момент честно пора переходить на что-то другое.

Что такое SQL Server Express#

Microsoft выпускает SQL Server в редакциях с общей кодовой базой: Enterprise, Standard, Web (для хостинг-провайдеров), Developer (возможности Enterprise, лицензия только для разработки и тестирования) и Express. Express - бесплатная продакшен-редакция. В ней тот же оптимизатор запросов, тот же движок хранения и тот же T-SQL, что и в остальных, а базу, созданную на Express, можно забэкапить и восстановить на Standard или Enterprise той же или более новой версии без всякого преобразования.

Начиная с SQL Server 2016 SP1 длинный список возможностей, которые раньше были только в Enterprise, работает во всех редакциях, включая Express. Это изменило смысл слова «Express»: это больше не урезанный движок, а полный движок с ограничениями по ёмкости.

Что доступно в Express:

  • Columnstore-индексы, in-memory OLTP (таблицы, оптимизированные для памяти), секционирование таблиц и сжатие данных - в пределах ограничений памяти Express.
  • Row-level security, динамическое маскирование данных и Always Encrypted.
  • Temporal tables, JSON-функции, оконные функции, STRING_AGG и всё остальное в современном T-SQL.
  • Query Store для отслеживания планов запросов и производительности во времени. Как им пользоваться, разобрано в статье Query Store и медленные запросы.
  • Модель восстановления full и бэкапы журнала транзакций, так что восстановление на момент времени возможно.

Чего в Express нет:

  • SQL Server Agent, встроенного планировщика задач. Никаких задач по расписанию, планов обслуживания и оповещений.
  • Сжатия бэкапов. Бэкапы работают; движок их просто не сжимает.
  • Database Mail, log shipping, групп доступности Always On и отказоустойчивых кластеров.
  • Репликации в роли издателя. Express может быть только подписчиком.
  • Resource Governor и других средств управления нагрузкой, доступных только в Enterprise.

SQL Server 2022 работает и на Linux, и именно так сегодня работает большинство размещённых на хостинге серверов Express. Движок тот же; различия в основном по краям - пути, настройка через mssql-conf вместо SQL Server Configuration Manager и несколько возможностей только для Windows. Эти различия разобраны в статье SQL Server на Linux.

Ограничения подробно#

ОграничениеSQL Server 2022 ExpressЧто это значит на практике
Размер базы10 GB на базуТолько файлы данных; журнал транзакций не считается
Память buffer pool1,410 MB на экземплярКэш страниц данных; процесс в целом использует больше
Кэш columnstore352 MB на экземплярВажно, только если вы используете columnstore-индексы
Данные, оптимизированные для памяти352 MB на базуВажно, только если вы используете in-memory OLTP
ВычисленияМеньшее из 1 сокета или 4 ядерЯдра сверх четырёх простаивают
Баз на экземпляр32,767 (как в других редакциях)Ограничение действует на базу, а не на сервер

Предел в 10 GB применяется к каждой базе отдельно и учитывает только файлы данных (.mdf и любые .ndf), а не файл журнала (.ldf). Два следствия стоит назвать прямо. Во-первых, экземпляр может держать несколько баз по 10 GB каждая - разным приложениям и так стоит иметь разные базы, и это заодно держит каждую под пределом. Во-вторых, большой журнал транзакций не съедает эти 10 GB; он съедает ваш диск, а это отдельная проблема, о которой ниже.

Ограничение памяти - потолок для buffer pool, кэша страниц данных, благодаря которому повторные чтения быстрые, а не для всего процесса. SQL Server также тратит память на планы запросов, соединения, сортировки и собственный код, так что нагруженный экземпляр Express обычно использует в сумме больше 1.4 GB. Потолок означает, что база, часто читаемые данные которой больше примерно 1.4 GB, будет читаться с диска чаще, чем на Standard. На быстром NVMe это стоит меньше, чем раньше, но это всё равно первое ограничение, которое вы почувствуете на приложении с большой нагрузкой на чтение.

Ограничение вычислений - четыре ядра. Сервер с большим числом ядер не сделает Express быстрее; сервер с меньшим даст Express меньше ресурсов.

Как понять, насколько вы близко#

Размер базы проверяется из любого окна запросов:

sql
-- Size of data and log files in the current databaseSELECT name, type_desc,       size * 8 / 1024 AS size_mb,       FILEPROPERTY(name, 'SpaceUsed') * 8 / 1024 AS used_mbFROM sys.database_files;-- Overall, including unallocated spaceEXEC sp_spaceused;

size - выделенный размер файла, а SpaceUsed - сколько из него занято данными. Предел в 10 GB применяется к выделенному размеру файлов данных, так что файл данных, выросший до 9.5 GB и наполовину пустой, ближе к потолку, чем можно подумать по его содержимому.

Чтобы увидеть, какие таблицы занимают место:

sql
SELECT TOP (20)       s.name + '.' + t.name AS table_name,       SUM(p.reserved_page_count) * 8 / 1024 AS reserved_mb,       SUM(CASE WHEN p.index_id IN (0, 1) THEN p.row_count END) AS row_countFROM sys.dm_db_partition_stats AS pJOIN sys.tables AS t ON t.object_id = p.object_idJOIN sys.schemas AS s ON s.schema_id = t.schema_idGROUP BY s.name, t.nameORDER BY reserved_mb DESC;

Запускайте это раз в месяц или включите в скрипт мониторинга. Наверху списка почти всегда оказываются логи, журналы аудита, сессии или blob-данные, которые никто не собирался хранить вечно.

Чтобы увидеть, как используется buffer pool:

sql
SELECT DB_NAME(database_id) AS db,       COUNT(*) * 8 / 1024 AS cached_mbFROM sys.dm_os_buffer_descriptorsGROUP BY database_idORDER BY cached_mb DESC;

Если общий объём кэша стоит на потолке, а задержка запросов растёт вместе с трафиком, ограничение - память. Если объём кэша заметно ниже потолка, проблема не в памяти, и более старшая редакция не поможет.

Что происходит на 10 GB#

Ничего постепенного. Когда файлу данных нужно вырасти, а рост вывел бы базу за 10 GB, в росте отказывают. Вставки и обновления, которым нужны новые страницы, падают с ошибкой вроде такой:

code
Could not allocate space for object 'dbo.AuditLog'.'PK_AuditLog' in database 'app'because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files,dropping objects in the filegroup, adding additional files to the filegroup, or settingautogrowth on for existing files in the filegroup.

Чтение продолжает работать, поэтому некоторые приложения выглядят полуживыми: страницы загружаются, но ничего не сохраняется. ALTER DATABASE, пытающийся увеличить файл сверх предела, отклоняется с сообщением о превышении лицензионного лимита в 10240 MB на базу.

Как вернуться под предел:

  1. Удалите то, что не нужно. Старые строки логов, истёкшие сессии, мягко удалённые записи. Удаляйте пачками (DELETE TOP (5000) ... WHERE CreatedAt < ... в цикле), чтобы каждая транзакция оставалась небольшой.
  2. Вынесите blob-данные. Файлы в колонках varbinary(max) - самый быстрый способ заполнить 10 GB. Положите их в объектное хранилище, а в таблице держите ключ.
  3. Сожмите. Сжатие страниц (ALTER TABLE dbo.AuditLog REBUILD WITH (DATA_COMPRESSION = PAGE)) доступно в Express и часто уменьшает большие таблицы с повторяющимися данными вдвое и больше ценой некоторой нагрузки на CPU при записи.
  4. Разделите по назначению. Архивные или отчётные данные могут жить во второй базе на том же экземпляре, со своими 10 GB.

Сжатие файла после этого (DBCC SHRINKFILE) возвращает выделенное место, но сильно фрагментирует индексы; сделайте это один раз после большой чистки, затем перестройте важные индексы и никогда не ставьте shrink в расписание.

Без SQL Server Agent: расписание без него#

Agent - то, что большинство руководств по SQL Server используют для ночных бэкапов, обслуживания индексов и обновления статистики. В Express его нет, поэтому эти задачи переезжают за пределы движка. Три рабочих варианта:

  • Планировщик хостинга. В RE:NODE тарифы SQL Server включают от 1 до 4 слотов для бэкапов, а вкладка Schedules выполняет упорядоченные задачи по cron-выражению - в том числе бэкап, - так что ночная копия - это настройка, а не скрипт, который вам приходится поддерживать живым. Бэкапы хранятся вне машины, которую они защищают, их можно заблокировать от ротации, скачать и восстановить одной кнопкой.
  • `sqlcmd` с другой машины по таймеру. Задача cron или запись в Планировщике заданий Windows на машине, которую вы контролируете, запускает sqlcmd с файлом скрипта - BACKUP DATABASE, обслуживание индексов, всё, что умеет T-SQL. Командная строка разобрана в статье sqlcmd и bcp, а сами команды бэкапа - в статье Бэкап и восстановление SQL Server.
  • Собственный исполнитель задач приложения. Worker service на .NET или задача Hangfire может выполнять T-SQL обслуживания по расписанию. Для статистики и чистки это нормально; для бэкапов хуже, потому что бэкап не должен зависеть от того, здорово ли приложение.
sql
-- A minimal nightly maintenance script for sqlcmdBACKUP DATABASE [app] TO DISK = N'/var/opt/mssql/backup/app.bak'    WITH INIT, CHECKSUM, STATS = 10;EXEC sp_updatestats;

Путь бэкапа выше - каталог бэкапов по умолчанию в установках на Linux; на хостинговом сервере он может быть другим, так что проверьте, прежде чем на него полагаться. Файл .bak, который остаётся на том же диске, что и база, - не бэкап ни в каком полезном смысле: копируйте его в другое место.

Другое, что обычно делает Agent, - обслуживание индексов и статистики. Статистика обновляется автоматически, когда меняется достаточно строк (AUTO_UPDATE_STATISTICS включён по умолчанию), и для большинства небольших баз этого хватает. Перестройка индексов на SSD и NVMe важна меньше, чем утверждают старые советы; перестраивайте индекс, когда можете показать, что фрагментация вредит конкретному запросу, а не по таймеру.

Подбор сервера под Express#

Поскольку Express ограничивает память и ядра, есть точка, после которой больший сервер ничего не даёт самому движку.

НагрузкаПамятьvCPUКомментарий
Одна небольшая база приложения, слабый трафик2 GB1Buffer pool ниже потолка, с запасом для ОС
Нагруженное приложение или несколько небольших баз3-4 GB2-3Buffer pool спокойно доходит до своего потолка в 1.4 GB
Несколько баз около 10 GB каждая4-6 GB3-4Диск и CPU важнее дополнительной памяти

Сверх примерно 4 GB общей памяти дополнительная RAM в основном не используется движком. Сверх четырёх ядер Express использовать их не может. Масштабироваться продолжает диск: каждая дополнительная база может занимать до 10 GB, а журналам, бэкапам и tempdb тоже нужно место. В RE:NODE линейка SQL Server идёт от Express Starter (2 GB, 10 GB диска, 1 vCPU) до Express Max (6 GB, 80 GB диска, 4 vCPU), начиная с $6 в месяц; старшие тарифы - это место для большего числа баз и полные четыре ядра, а не больше кэша.

Следите не только за данными, но и за журналом транзакций. В модели восстановления full журнал растёт, пока его не усечёт бэкап журнала, а без Agent, который делал бы такие бэкапы, база в режиме full, которую никто не бэкапит, раздувает журнал, пока не кончится диск. Проверьте, какую модель используют ваши базы:

sql
SELECT name, recovery_model_desc FROM sys.databases;

Если вы не делаете бэкапы журнала, используйте SIMPLE. Этот компромисс объясняет статья Модели восстановления и рост журнала.

Когда Express недостаточно#

Уходите с Express, когда верно одно из следующего, а не раньше:

  • Одна база движется за 10 GB, а чистка, сжатие и разделение нереалистичны. Редакция Standard поднимает предел размера до ограничений операционной системы.
  • Рабочий набор намного больше 1.4 GB, и вы можете показать, что узкое место - чтение с диска. Standard допускает buffer pool до 128 GB.
  • Вам нужна высокая доступность внутри SQL Server - группы доступности, отказоустойчивые кластеры, log shipping. Ничего из этого в Express нет.
  • Вам нужны задачи через Agent, оповещения Database Mail или репликация в роли издателя, а внешний планировщик не подходит.

Обычные направления - редакция Standard на сервере, который вы лицензируете сами (по ядрам или по серверу плюс CAL, это существенные расходы), Azure SQL Database или Azure SQL Managed Instance, либо другой движок. Для нового проекта без зависимости от SQL Server у PostgreSQL вообще нет ограничений редакций; статья Какую базу данных выбрать сравнивает их по задачам. Перевод существующей базы на редакцию выше - это бэкап и восстановление: .bak из Express без изменений восстанавливается на Standard или Enterprise той же или более новой версии. Обратное направление и правила версий разобраны в статье Перенос базы на хостинг SQL Server.

Чего делать не стоит, так это запускать в продакшене редакцию Developer, чтобы обойти ограничения. Она бесплатна и содержит все возможности, но её лицензия запрещает использование в продакшене.

FAQ#

SQL Server Express бесплатен для коммерческого использования?

Да. Express лицензирован для продакшена и коммерческого использования бесплатно. Хостингу вы платите за сервер, на котором он работает, а не за лицензию SQL Server.

Включает ли предел 10 GB журнал транзакций?

Нет. Считаются только файлы данных. Журнал может вырасти больше 10 GB, ограничиваясь лишь местом на диске, поэтому неуправляемый журнал в модели восстановления full - реальный риск на небольших серверах.

Можно ли держать несколько баз по 10 GB на одном экземпляре Express?

Да. Ограничение действует на каждую базу. Разносить несвязанные данные по разным базам - нормальная практика, и это держит каждую под пределом.

Станет ли Express быстрее, если дать ему больше RAM?

До определённого момента. Buffer pool останавливается на 1,410 MB, так что память сверх того, что нужно этому потолку, операционной системе и остальному движку, не используется. Если кэш уже на потолке, а узкое место - чтение с диска, следующий шаг - лучшие индексы или другая редакция, а не больше RAM.

Можно ли восстановить бэкап Express на Standard или Azure SQL?

На Standard или Enterprise той же или более новой версии - да, напрямую. Azure SQL Database не восстанавливает файлы .bak; туда переезжают через экспорт .bacpac или инструмент миграции. Azure SQL Managed Instance нативные бэкапы восстанавливает.

Поддерживает ли SQL Server Express хранимые процедуры и триггеры?

Да. Доступен весь T-SQL, включая хранимые процедуры, функции, триггеры, представления, CTE и оконные функции. Ограничения касаются ёмкости и нескольких серверных возможностей, а не языка.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000