Если кратко: Возникла необходимость перенести таблицу вместе с LOB в другую файловую группу. Если я правильно понимаю, сделать это можно либо через пересоздание таблицы в этой группе и перенос данных, либо через пересоздание индекса с партиционированием. И то, и другое довольно геморойно — есть ли более простой путь?
Если не кратко: SQL Server 2012. Задача — сжать базу: если просто на месте пережать таблицы а потом сделать shrink — получится дико фрагментированная каша + вся операция займёт несколько дней и остановить её будет нельзя. Поэтому вместо этого хочу разнести данные по отдельным файловым группам, а затем просто shrink truncate_only. Соответственно всё перенёс, остались только LOB-Data, с которыми как не крутись гемор. Пока склоняюсь к удалению индексов исходной таблицы, переименованию исходной таблицы, создание новой, копирование данных, удаление исходной, пересоздание индексов. Но может есть способ проще?
"Generate script..." не предлагать — таблиц очень много, я замучаюсь выбирать что именно скриптовать, проще самому что-то накатать.
Как работать SSIS я не знаю, если это можно сделать с его помощью, хотелось бы ссылку на статью с пояснениями как примерно подобное выглядит.
Empty data file не работает с primary file group (по крайней мере у меня ругнулось что не может перенести данные из основного файла базы)
Шринкануть primary с заданием требуемого размера можно, но это опять же долго, хотелось бы это делать только в крайнем случае.
ARI ARI ARI... Arrivederci!
Re: [SQL Server] Перенос LOB Data в другую filegroup
S>Пока склоняюсь к удалению индексов исходной таблицы, переименованию исходной таблицы, создание новой, копирование данных, удаление исходной, пересоздание индексов. Но может есть способ проще?
Да есть.
Делай трансфер через временную схему. Таблицы можно между ними перебрасывать, имена при этом могут совпадать, в т.ч. ключей индексов и т.п.
Re[2]: [SQL Server] Перенос LOB Data в другую filegroup
Здравствуйте, rm822, Вы писали:
S>>Пока склоняюсь к удалению индексов исходной таблицы, переименованию исходной таблицы, создание новой, копирование данных, удаление исходной, пересоздание индексов. Но может есть способ проще? R>Да есть. R>Делай трансфер через временную схему. Таблицы можно между ними перебрасывать, имена при этом могут совпадать, в т.ч. ключей индексов и т.п.
В этом нет особого смысла — перенос всё равно будет идти в эксклюзивном режиме, иначе есть шанс потерять новые данные в таблице, а значит нет особой необходимости беспокоиться о недоступности таблицы.
ARI ARI ARI... Arrivederci!
Re: [SQL Server] Перенос LOB Data в другую filegroup
Здравствуйте, Somescout, Вы писали:
S>Если кратко: Возникла необходимость перенести таблицу вместе с LOB в другую файловую группу. Если я правильно понимаю, сделать это можно либо через пересоздание таблицы в этой группе и перенос данных, либо через пересоздание индекса с партиционированием. И то, и другое довольно геморойно — есть ли более простой путь?
S>...
Не смотря на трудоемкость того и другого подхода, между ними есть большая разница для версий 2012+. Если идти по пути прямого переноса данных, то в этом в варианте вам нужно либо изолировать пользователей от доступа к данным, либо обеспечить повторный перелив исправлений. В варианте с секционированием, который нужно рассматривать как временный, весь перенос данных сводится к пересозданию индексов с удалением уже существующих, так вот в версии 2012 это можно делать в режиме онлайн, даже несмотря на то что в базовой таблице используются LOB данные.
Доступные способы переноса LOB данных вы уже обозначили, других на данный момент нет. Теперь пара слов о том как облегчить себе страдания...
Попробовал SSDT на вашей задачи в варианте прямого переноса данных и он успешно с ней справился. В проекте у объектов таблица и кластерный индекс я изменил файловую группу. Создал schema compare между проектом и исходной БД, предварительно сняв в настройках опцию "Ignore filegroup placement" на вкладке General. По результатам сравнения получил скрипт обновления БД, который сводится к простому — создается таблица и индекс на новой ФГ с другим именем, переносятся данные через insert, удаляются старые объекты, переименовываются новые и все это завернуто в транзакцию. Весь скрипт сгенерировал SSDT, я только поменял принадлежность объектов к файловой группе и выбрал таблицы по которым нужно проверять изменения. В общем рекомендую.
Re[2]: [SQL Server] Перенос LOB Data в другую filegroup
Здравствуйте, Olaf, Вы писали:
O>Не смотря на трудоемкость того и другого подхода, между ними есть большая разница для версий 2012+. Если идти по пути прямого переноса данных, то в этом в варианте вам нужно либо изолировать пользователей от доступа к данным, либо обеспечить повторный перелив исправлений. В варианте с секционированием, который нужно рассматривать как временный, весь перенос данных сводится к пересозданию индексов с удалением уже существующих, так вот в версии 2012 это можно делать в режиме онлайн, даже несмотря на то что в базовой таблице используются LOB данные.
Изоляция пользователей не проблема на самом деле, технический перерыв предусмотрен.
O>Доступные способы переноса LOB данных вы уже обозначили, других на данный момент нет. Теперь пара слов о том как облегчить себе страдания...
O>Попробовал SSDT на вашей задачи в варианте прямого переноса данных и он успешно с ней справился. В проекте у объектов таблица и кластерный индекс я изменил файловую группу. Создал schema compare между проектом и исходной БД, предварительно сняв в настройках опцию "Ignore filegroup placement" на вкладке General. По результатам сравнения получил скрипт обновления БД, который сводится к простому — создается таблица и индекс на новой ФГ с другим именем, переносятся данные через insert, удаляются старые объекты, переименовываются новые и все это завернуто в транзакцию. Весь скрипт сгенерировал SSDT, я только поменял принадлежность объектов к файловой группе и выбрал таблицы по которым нужно проверять изменения. В общем рекомендую.
Скрипт для генерации скрипта я уже и сам написал (громоздко, но не так сложно как я думал — для варианта с копированием), но тут возникла одна проблема: в некоторых таблицах используется тип timestamp (rowversion) перенести который напрямую нельзя. Так что скорее всего либо переносить через партиционирование, либо забить на оставшиеся таблицы и просто shrink file к заданному размеру — там не так много осталось.
Но, если я правильно понимаю, если я сделаю партиционирование таблицы с существующим кластерным индексом, кластерный индекс будет пересоздаваться два раза (первый раз с партиционированием, второй раз оригинальный). Будут ли во второй раз (при восстановлении оригинального индекса) перемещаться lob-data в пределах файла, или только row-data? Логика подсказывает, что раз lob-data в принципе не участвуют в индексе, то перемещаться они не должны.
Я вообще не вижу лёгкого пути для универсального генератора скрипта партиционирования на T-SQL... скорее всего придётся взять несколько самых распространённых вариантов (для целого, строки, даты) и захардкодить их их.
ARI ARI ARI... Arrivederci!
Re[2]: [SQL Server] Перенос LOB Data в другую filegroup
Здравствуйте, rm822, Вы писали:
S>>Пока склоняюсь к удалению индексов исходной таблицы, переименованию исходной таблицы, создание новой, копирование данных, удаление исходной, пересоздание индексов. Но может есть способ проще? R>Да есть. R>Делай трансфер через временную схему. Таблицы можно между ними перебрасывать, имена при этом могут совпадать, в т.ч. ключей индексов и т.п.
Хм, пожалуй поправлюсь: с временной схемой и правда легче, поскольку для идентичных таблиц создаются идентичные автоматические индексы (для первичного ключа, например), и если просто переименовать таблицу, то происходит конфликт имён индексов при создании новой.