Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2 3      [все]
 Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Добрый день!

Имеется резервная копия БД в виде совокупности бекапов:
Имя файла Размер
DBName.bak 11 гб
m01.bak 497 мб
m02.bak 251 мб
... ...
m99.bak 331 мб


Вопрос следующий - каким образом восстановить базу целиком?
1) каждый .bak по отдельности восстанавливать
2) или в главной резервной копии (DBName.bak) есть просто ссылки на эти секции и достаточно запустить на восстановление эту главную копию?

И второй вопрос - попробовал восстановить главную копию (DBName.bak) на SQL Server 2017, но выдало ошибку
system.data.sqlclient.sqlerror
Создание резервной копии баз данных производилось на сервере, на котором работала версия 8.00.2055...
Но с этим разобрался, нашёл на вашем ресурсе решение. Но смутил тот факт, что при попытке восстановить, например m12.bak, sql такой ошибки версии не выдает и спокойной восстанавливает кусок БД.
12 ноя 19, 15:58    [22014590]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 32614
Блог
PavelPN,

А с чего вы взяли, что это одна бд?
12 ноя 19, 16:03    [22014594]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Критик, так было заявлено админом, когда он покидал нас. Ну и лежат бекапы в одной папке, хотя это, конечно, такой себе показатель.
12 ноя 19, 16:11    [22014603]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 32614
Блог
PavelPN,

Сначала изучите, что там с помощью RESTORE FILELISTONLY, затем гляньте справку по команде
https://docs.microsoft.com/ru-ru/sql/t-sql/statements/restore-statements-transact-sql?view=sql-server-ver15
12 ноя 19, 16:14    [22014608]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN
Но смутил тот факт, что при попытке восстановить, например m12.bak, sql такой ошибки версии не выдает и спокойной восстанавливает кусок БД.

смущает вот это: "спокойной восстанавливает кусок БД".
чтобы восстановить "кусок", база должна быть весьма специфической структуры (несколько ФГ),
и синтаксис рестора там не сильно стандартный,
скорее вы пишете фигню.
12 ноя 19, 16:32    [22014619]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Критик,
Запрос
restore filelistonly
from disk='E:\BackUp\DBName.bak'


Результат
LogicalNamePhysicalNameTypeFileGroupNameSizeIsPresent
cena_Data d:\Program Files\Microsoft SQL Server\MSSQL\data\cena.mdf D PRIMARY 11418992640 1
cena_Log D:\Program Files\Microsoft SQL Server\MSSQL\Data\cena_log.ldf L NULL 2097152000 0


Запрос
restore filelistonly
from disk='E:\BackUp\m85.bak'

Результат
LogicalNamePhysicalNameTypeFileGroupNameSizeIsPresent
flnst_Data D:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\flnst85.mdf D PRIMARY 1572864000 1
flnst_Log D:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\flnst85_1.ldf L NULL 271450112 1


У них разные логические имена. Наверное, такого не должно быть, если в теории это бекапы одной базы.

Сообщение было отредактировано: 12 ноя 19, 17:01
12 ноя 19, 16:56    [22014640]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Yasha123, если бы я не пробовал этот вариант, то не отписывал о нем в сообщение. так что никакой "фигни" здесь нет.
12 ноя 19, 16:59    [22014644]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36505
У вас бэкапы разных баз. А вы всем вещаете, что это якобы бэкап одной базы.

Сообщение было отредактировано: 12 ноя 19, 17:03
12 ноя 19, 17:03    [22014646]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN
Yasha123, если бы я не пробовал этот вариант, то не отписывал о нем в сообщение. так что никакой "фигни" здесь нет.

еще какая фигня.
оба представленных бэкапа имеют по одному файлу данных,
так что никакой "кусок" восстановить нельзя.
только целиком
12 ноя 19, 17:17    [22014659]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Приношу извинения, что повёл вас не в ту степь. У нас айтишник ушёл. Кратко обрисовал ситуацию как есть и всё с концами. Нового ещё не нашли.

Спасибо, теперь хотя бы будем в курсе, что DBName.bak и m01.bak - m99.bak это резервные копии разных баз. Но вопрос, тем не менее, остается открытым.
Есть совокупность m01.bak - m99.bak резервных копий (у них по инструкции RESTORE — FILELISTONLY возвращается одно логическое имя). Каким образом их восстановить и собрать в единую БД?
12 ноя 19, 17:19    [22014662]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN

Есть совокупность m01.bak - m99.bak резервных копий (у них по инструкции RESTORE — FILELISTONLY возвращается одно логическое имя). Каким образом их восстановить и собрать в единую БД?

теепрь сделайте restore headeronly
тем, у которых внутри одна и та же база.
и покажите, что там.
12 ноя 19, 17:24    [22014673]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36505
PavelPN,

Еще раз. С чего вы решили, что вам надо все эти бэкапы собирать в _одну_ базу?
12 ноя 19, 17:26    [22014678]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7014
PavelPN,

у Вас на сервер сейчас сколько баз, можете подсчитать?
12 ноя 19, 17:31    [22014685]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Гавриленко Сергей Алексеевич, я развернул несколько экземпляров этих бекапов. Таблицы в них содержатся одинаковые, но в каждом экземпляре содержатся сведения только по одной территории. Например, в m01 только данные по Москве, в m20 - по Питеру, в m55 - по Новгороду. Ну и я предположил, что вся БД просто разбита по территориям.

Yasha123, сейчас сделаю и выложу.
12 ноя 19, 17:38    [22014696]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
PavelPN
Гавриленко Сергей Алексеевич, я развернул несколько экземпляров этих бекапов. Таблицы в них содержатся одинаковые, но в каждом экземпляре содержатся сведения только по одной территории. Например, в m01 только данные по Москве, в m20 - по Питеру, в m55 - по Новгороду. Ну и я предположил, что вся БД просто разбита по территориям.
Так и баз несколько?

Скорее всего, в вашей системе база данных состоит из множества баз данных.
А в базе, которая в "DBName.bak", есть вьюха, объединяющая таблицы этих баз.
Ждём headeronly...

В общем, тут самый правильный совет - искать специалиста :-)
12 ноя 19, 17:42    [22014701]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
Гавриленко Сергей Алексеевич
PavelPN,

Еще раз. С чего вы решили, что вам надо все эти бэкапы собирать в _одну_ базу?

не, он не все базы собрался в одну собрать,
хотя и мне так сперва показалось.
он говорит, там, где бэкапы одной и той же базы,
что именно восстанавливать, вот смотрите:
автор
Есть совокупность m01.bak - m99.bak резервных копий (у них по инструкции RESTORE — FILELISTONLY возвращается одно логическое имя). Каким образом их восстановить и собрать в единую БД?

т.е. там, где несколько бэкапов одной и той же базы, он снова думает, что это ее "куски".

PavelPN: это не куски одной базы, это ее(одной и той же базы: "одно логическое имя" в ваших терминах) бэкапы
на разные моменты времени
12 ноя 19, 17:45    [22014703]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
PavelPN: это не куски одной базы, это ее(одной и той же базы: "одно логическое имя" в ваших терминах) бэкапы
на разные моменты времени
В FILELISTONLY ведь показывается логическое имя файлов.
Одинаковое - потому что эти базы делали копированием базы-заготовки.

Т.е. повторю моё предположение:
Это одна база данных (как юридический термин(, состоящее из множества баз данных (mssql), по одной на регион, а в главной базе есть либо вьюхи, либо ХП, которые работают с этим множеством баз как с одной.

В общем, надо посмотреть headeronly, там будет имя базы, которое было при бакапе.
12 ноя 19, 18:01    [22014720]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7014
PavelPN,

у Вас на сервер сейчас сколько баз, можете подсчитать?
12 ноя 19, 18:04    [22014722]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Запрос:
restore headeronly
from disk='E:\BackUp\m01'

Результат:
BackupName BackupType Position DeviceType UserName ServerName DatabaseName DatabaseVersion DatabaseCreationDate BackupSize FirstLSN LastLSN CheckpointLSN DatabaseBackupLSN BackupStartDate BackupFinishDate UnicodeLocaleId CompatibilityLevelBackupTypeDescription
flnst01--Full Database Backup 112syadminCA-WEB-05flnst016112011-12-20 16:14:43.00050992998416170000000375000721617000000040500001161700000003750007216170000000294000722019-10-17 13:25:49.0002019-10-17 13:25:52.000104980Database


Запрос
restore headeronly
from disk='E:\BackUp\m12'

Результат
BackupName BackupType Position DeviceType UserName ServerName DatabaseName DatabaseVersion DatabaseCreationDate BackupSize FirstLSN LastLSN CheckpointLSN DatabaseBackupLSN BackupStartDate BackupFinishDate UnicodeLocaleId CompatibilityLevelBackupTypeDescription
flnst12-Full Database Backup112syadminCA-WEB-05flnst126112011-09-29 13:50:59.00016900864038810000000161000383881000000017700001388100000001610003838810000000123000382019-09-02 14:49:48.0002019-09-02 14:49:49.000104980Database


Запрос
restore headeronly
from disk='E:\BackUp\m24'

Результат
BackupName BackupType Position DeviceType UserName ServerName DatabaseName DatabaseVersion DatabaseCreationDate BackupSize FirstLSN LastLSN CheckpointLSN DatabaseBackupLSN BackupStartDate BackupFinishDate UnicodeLocaleId CompatibilityLevelBackupTypeDescription
flnst24-Full Database Backup112syadminCA-WEB-05flnst246112011-12-20 16:21:11.00012808243215760000000053000371576000000006900001157600000000530003715760000000030000372019-09-11 12:43:20.0002019-09-11 12:43:22.000104980Database
12 ноя 19, 18:08    [22014727]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Владислав Колосов, пока не могу сказать. У меня доступа к продакшн серверу нет. Я на своей машине этим занимаюсь. Попробую завтра узнать. Я понял о чем вы говорите. Т.е. вполне вероятно, что у нас 100 баз, где 1 база под каждую территорию выделена.

Сообщение было отредактировано: 12 ноя 19, 18:15
12 ноя 19, 18:11    [22014729]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
msLex
Member

Откуда:
Сообщений: 7101
PavelPN, ну так написано же

DatabaseName
flnst01
flnst12
flnst24
12 ноя 19, 18:12    [22014731]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Блин, жестяк. Походу реально под каждую территорию физически создана одна база. Это нормальная вообще практика?
12 ноя 19, 18:18    [22014735]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN
Блин, жестяк. Походу реально под каждую территорию физически создана одна база. Это нормальная вообще практика?

ну кто ж знает-то.
может, вы каждой территории высылаете ее собственную базу раз в неделю,
тогда нормально.
вы видите все, а они только свое.
а была бы одна база, как от нее получить "кусок" в виде бэкапа?
12 ноя 19, 18:38    [22014749]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7014
PavelPN,

это же зависит от разых факторов, в том числе от обслуживания баз. Например, переиндексация выполняется по регионам по расписанию. Или вы захотите перенести базу на выделенный региональный сервер, или каждый регион сильно нагружен запросами. Если это просто коллектор данных, то обычно так не делают.
12 ноя 19, 18:47    [22014757]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
Владислав Колосов
... или каждый регион сильно нагружен запросами.

о да, у каждого региона уж такая загруженность...
каждая базенка мегабайтами исчисляется,
и это бэкапы без компрессии, сервер-то 2005
12 ноя 19, 18:52    [22014758]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
вообще что-то ваши показания расходятся с тем, что в бэкапах.
сервер-исходник 2005, хотя и в совместимости 80 (2000).
откуда бы ему взять, что исходный сервер 2000?
12 ноя 19, 18:56    [22014759]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
PavelPN
Блин, жестяк. Походу реально под каждую территорию физически создана одна база. Это нормальная вообще практика?
Бывает. Особенно раньше. Гениальные программисты, дрожа от предвкушения гигантских объёмов данных (у нас таблицы до МИЛЛИОНА строк, представляете!!!), часто разбивали базу на несколько вот таким образом.

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


Владислав Колосов,
Да там объёмы мизерные, базы по 300 мегабайт. Не терабайт, и даже не гигабайт.
12 ноя 19, 19:07    [22014766]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
вообще что-то ваши показания расходятся с тем, что в бэкапах.
сервер-исходник 2005, хотя и в совместимости 80 (2000).
откуда бы ему взять, что исходный сервер 2000?
А что не сходится? Да, базы работают(-ли) на 2005, в режиме совместимости с 2000м
12 ноя 19, 19:10    [22014768]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
alexeyvg
Yasha123
вообще что-то ваши показания расходятся с тем, что в бэкапах.
сервер-исходник 2005, хотя и в совместимости 80 (2000).
откуда бы ему взять, что исходный сервер 2000?
А что не сходится? Да, базы работают(-ли) на 2005, в режиме совместимости с 2000м


не сходится с вот этим:
автор
Создание резервной копии баз данных производилось на сервере, на котором работала версия 8.00.2055...

бэкапилось на 2005-ом, а не на 2000-ом.
и наплевал он на совместимость базы
12 ноя 19, 19:13    [22014771]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
alexeyvg
А что не сходится? Да, базы работают(-ли) на 2005, в режиме совместимости с 2000м
не сходится с вот этим:
автор
Создание резервной копии баз данных производилось на сервере, на котором работала версия 8.00.2055...
бэкапилось на 2005-ом, а не на 2000-ом.
и наплевал он на совместимость базы
Непонятно, что не сходится.

Да, работал много лет на 2005, базы были при этом в режиме совместимости с 2000-м.
При этом базы переходили с сервера на сервер (минимум 2 раза), и всё это были 2005-е серверы.
А когда то, в 2000-м году (или позже), их создали на 2000-м (и тоже неизвестно сколько раз переносили с одного 2000-го на другой).
12 ноя 19, 19:26    [22014780]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
alexeyvg
Да, работал много лет на 2005, базы были при этом в режиме совместимости с 2000-м.
При этом базы переходили с сервера на сервер (минимум 2 раза), и всё это были 2005-е серверы.
И, само собой, много раз делали бакапы на 2005-м. Конкретно этот бакап в сентябре.
12 ноя 19, 19:27    [22014782]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
не понимаю, при чем тут история вашей жизни,
но бэкапивший сервер был 2005,
а ошибка говорит, что 2000.

и наплевать, на каком сервере база родилась, важно, каков формат данного бэкапа. те. версия бэкапившего сервера. и это 2005, а не 2000
12 ноя 19, 19:35    [22014790]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
не понимаю, при чем тут история вашей жизни,
Это была история обсуждаемой базы, если вы не поняли.
Yasha123
но бэкапивший сервер был 2005,
а ошибка говорит, что 2000.
А, на ошибку в первом посте я не посмотрел, благо к теме она не относится.

Делов то, пробовал человек разные бакапы, пытался разобраться...
А может, действительно 2005м там и не пахло, был только 2000-й
Это же не имеет отношения к проблеме автора.
12 ноя 19, 22:06    [22014850]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
еще как относится.
ТС, у вас базы минимум с двух разных серверов.
сделайте restore headeronly и бэкапу "главной базы" тоже.
проверьте колонку server name,
там будет другой сервер.
не знаю, что это означает в вашем случае,
но, например, может оказаться, что из одной базы в другую обращаются через linked server
13 ноя 19, 07:42    [22014952]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
alexeyvg

А может, действительно 2005м там и не пахло, был только 2000-й.

как же не пахло, если restore headeronly показывает версию базы 611.
вам говорю, там минимум 2 сервера, но вы меня упорно не слышите

Сообщение было отредактировано: 13 ноя 19, 07:46
13 ноя 19, 07:45    [22014955]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
еще как относится.
может оказаться, что из одной базы в другую обращаются через linked server
Да, тут вы правы, для восстановления баз может оказаться недостаточно просто их все восстановить.
13 ноя 19, 08:37    [22014973]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
Yasha123
вам говорю, там минимум 2 сервера, но вы меня упорно не слышите
Да, про 2 сервера теперь понял :-)
Скорее, так и есть (хотя всё таки ТС мог для главной базы достать какой то старый бакап, а то делать систему на многих серверах как то совсем усложнение, для таких небольших объёмов)
13 ноя 19, 08:43    [22014975]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
PavelPN
Критик, так было заявлено админом, когда он покидал нас

Уверен, - сейчас этот админ сидит в темноте и хохочет гомерическим смехом, запрокинув голову :)

Ну прикольнулся человек перед уходом, ну потроллил, ну что уж тут такого :)
13 ноя 19, 08:54    [22014981]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Добрый день. Спасибо большое за помощь, хотя бы представление получили общее о том, как утроено всё.
Получилось посмотреть как это на рабочем сервере лежит.
Вы оказались полностью правы, под каждую территорию отдельно создана БД и похоже эта DBName на 11 гб выступает как агрегатор сведений и содержит всевозможные представления из всех этих 100 баз.
Каким образом они связаны я не знаю. Тут уж просто будем искать специалиста, чтобы всё это поднимал оперативно.
А пока я хочу у себя развернуть территориальные базы, хотя бы для локального доступа к ним. Можете подсказать скрипт как их в автоматическом режиме восстановить? При условии, что некоторые номера почему-то пропущены. Т.е. есть m07.bak, а после него m09.bak
А то все руками поднимать это трата времени, а его не хватает сейчас крайне.
14 ноя 19, 10:45    [22015937]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN
похоже эта DBName на 11 гб выступает как агрегатор сведений и содержит всевозможные представления из всех этих 100 баз.

были бы там одни представления, была бы база размером в мегабайт.
у вас же как раз наоборот, все гигабайты там,
а остальные базы - крошки какие-то.
так что в этой базе своего добра хватает.
14 ноя 19, 11:01    [22015963]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1145
PavelPN, писал я такой скрипт, найти не могу, не сохранил, видимо.

1) включаете xp_cmdshell через sp_configure
2) Читаете список файлов во временную таблицу:
declare @files table (ID int IDENTITY, FileName varchar(100))

insert into @files execute xp_cmdshell 'dir c:\ /b'

select * from @files


Далее в курсоре по каждому файлу:
3) Через динамический SQL формируете команду на restore headeronly, чтобы получить название базы.
4) Аналогично - restore filelistonly, для получения списка файлов для базы.
5) Динамическим SQL генерируете команду на восстановление базы, выполняете.

В принципе, все, что нужно.
14 ноя 19, 11:05    [22015966]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Yasha123, согласен с вами. Учитывая увиденные таблицы и их содержимое, я вообще не понимаю что там хранится.

Minamoto, прошу прощения, но мои знания в t-sql ограничиваются пользовательскими селектами.
И используемые вами понятия "курсора" и "динамического sql" мне, к сожалению, даже не говорят ни о чем.

Если вам не будет напряжно и есть время, могу я попросить вас помочь со скриптом. Понять написанный код я более менее смогу, но написать самому, я думаю у меня займет пару дней.
14 ноя 19, 11:33    [22016009]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
Minamoto
PavelPN, писал я такой скрипт, найти не могу, не сохранил, видимо.

1) включаете xp_cmdshell через sp_configure
2) Читаете список файлов во временную таблицу:
declare @files table (ID int IDENTITY, FileName varchar(100))

insert into @files execute xp_cmdshell 'dir c:\ /b'

select * from @files



включать xp_cmdshell не обязательно
то же самое можно получить процедурой xp_dirtree
например,
exec xp_dirtree 'c:\temp',1,1
14 ноя 19, 11:46    [22016031]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1145
komrad

включать xp_cmdshell не обязательно
то же самое можно получить процедурой xp_dirtree
например,
exec xp_dirtree 'c:\temp',1,1

Да, но я помню, что перешел именно на xp_cmdshell для большего удобства - в утилите dir там можно более гибко управлять набором возвращаемых файлов, использовать маски, фильтровать и т.п.
14 ноя 19, 11:51    [22016036]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN
мои знания в t-sql ограничиваются пользовательскими селектами.
И используемые вами понятия "курсора" и "динамического sql" мне, к сожалению, даже не говорят ни о чем.

Если вам не будет напряжно и есть время, могу я попросить вас помочь со скриптом. Понять написанный код я более менее смогу, но написать самому, я думаю у меня займет пару дней.

вот именно.
вам проще скидать результаты restore filelistonly в одну таблицу
и копипастом сделать скрипт для всех баз.
на все про все макс. 10 минут на все 100 баз.

у вас же все пути, куда будете складывать файлы баз, одни и те же.
остается размножить 1 скрипт 100 раз и позаменять имя базы и имена файлов
14 ноя 19, 12:11    [22016062]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Yasha123,

USE [master];
go

RESTORE DATABASE [flnst01] FROM  DISK = N'E:\BackUp\m01.bak' WITH  FILE = 1,  MOVE N'flnst_Data' TO N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\flnst01.mdf',  MOVE N'munst_Log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\flnst01_1.ldf',  NOUNLOAD,  STATS = 5
GO

RESTORE DATABASE [flnst02] FROM  DISK = N'E:\BackUp\m02.bak' WITH  FILE = 1,  MOVE N'flnst_Data' TO N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\flnst02.mdf',  MOVE N'munst_Log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\flnst02_1.ldf',  NOUNLOAD,  STATS = 5
GO


Таким образом вы имеете в виду?
14 ноя 19, 12:20    [22016070]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
PavelPN,
у вас снова что-то не то с версиями.
если вы на 2017-ый сервер восстанавливаете,
почему в путях MSSQL12.MSSQLSERVER?

да и не кладите файлы на системный диск,
на другой сложите.

так-то да, должно быть типа такого:

restore database [flnst01] 
from disk = N'E:\BackUp\m01.bak' with
move N'flnst_Data' to N'F:\DATA\flnst01.mdf',  
move N'munst_Log'  to N'F:\DATA\flnst01_log.ldf'
14 ноя 19, 12:29    [22016086]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
PavelPN,

а какая версия сервера куда базы надо восстановить?
покажите
select @@version

К сообщению приложен файл (get_restorescript_2005.txt - 8Kb) cкачать

Сообщение было отредактировано: 14 ноя 19, 12:31
14 ноя 19, 12:29    [22016087]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1145
PavelPN, типа того...

Только я таки не поленился, написал скрипт.

Используйте на свой страх и риск :)

ЗЫ: Не забудьте правильные директории указать, для отладки замените последний "EXEC sp_executesql @sql" на "PRINT @sql"
Если не будет выполняться с ошибкой, что возвращаемый набор данных не соответствует описанному в таблицах @header и @filelist - приведите их описание к тому набору полей, которое возвращается вашими командами.

+
SET NOCOUNT on
DECLARE 
    @cmd varchar(8000), 
    @sql nvarchar(MAX), 
    @folder_bak varchar(max) = 'D:\Backups', 
    @folder_files varchar(max)= 'D:\SQLData', 
    @bak_name nvarchar(max);

declare @files table (ID int IDENTITY, FileName nvarchar(max) NULL)

declare @header table (
	BackupName nvarchar(128),
	BackupDescription nvarchar(255),
	BackupType tinyint,
	ExpirationDate datetime,
	Compressed tinyint,
	Position smallint,
	DeviceType tinyint,
	UserName nvarchar(128),
	ServerName nvarchar(128),
	DatabaseName nvarchar(128),
	DatabaseVersion int,
	DatabaseCreationDate datetime,
	BackupSize bigint,
	FirstLSN decimal(25,0),
	LastLSN decimal(25,0),
	CheckpointLSN decimal(25,0),
	DatabaseBackupLSN decimal(25,0),
	BackupStartDate datetime,
	BackupFinishDate datetime,
	SortOrder smallint,
	CodePage smallint,
	UnicodeLocaleId int,
	UnicodeComparisonStyle int,
	CompatibilityLevel tinyint,
	SoftwareVendorId int,
	SoftwareVersionMajor int,
	SoftwareVersionMinor int,
	SoftwareVersionBuild int,
	MachineName nvarchar(128),
	Flags int,
	BindingID uniqueidentifier,
	RecoveryForkID uniqueidentifier,
	Collation nvarchar(128),
	FamilyGUID uniqueidentifier,
	HasBulkLoggedData bit,
	IsSnapshot bit,
	IsReadOnly bit,
	IsSingleUser bit,
	HasBackupChecksums bit,
	IsDamaged bit,
	BeginsLogChain bit,
	HasIncompleteMetaData bit,
	IsForceOffline bit,
	IsCopyOnly bit,
	FirstRecoveryForkID uniqueidentifier,
	ForkPointLSN decimal(25,0),
	RecoveryModel nvarchar(60),
	DifferentialBaseLSN decimal(25,0),
	DifferentialBaseGUID uniqueidentifier,
	BackupTypeDescription nvarchar(128),
	BackupSetGUID uniqueidentifier,
	CompressedBackupSize bigint,
	Containment tinyint)

DECLARE @filelist table (
	LogicalName nvarchar(128),
	PhysicalName nvarchar(260),
	Type nchar(1),
	FileGroupName nvarchar(128),
	Size bigint,
	MaxSize bigint,
	FileId bigint,
	CreateLSN decimal(25,0),
	DropLSN decimal(25,0),
	UniqueId uniqueidentifier,
	ReadOnlyLSN decimal(25,0),
	ReadWriteLSN decimal(25,0),
	BackupSizeInBytes bigint,
	SourceBlockSize int,
	FileGroupId int,
	LogGroupGUID uniqueidentifier,
	DifferentialBaseLSN decimal(25,0),
	DifferentialBaseGUID uniqueidentifier,
	IsReadOnly bit,
	IsPresent bit,
	TDEThumbprint varbinary(20))

SET @cmd = 'dir ' + @folder_bak + ' /b | findstr /i "\.bak$"'

insert into @files execute xp_cmdshell @command_string = @cmd

DECLARE cur CURSOR FOR
SELECT FileName
FROM @files
WHERE FileName IS NOT NULL

OPEN cur
FETCH FROM cur INTO @bak_name
        
WHILE @@FETCH_STATUS = 0
BEGIN

    DELETE FROM @header;
    DELETE FROM @filelist;

    BEGIN TRY
        SET @sql = 'RESTORE HEADERONLY FROM DISK=''' + @folder_bak + '\' + @bak_name + ''';'
        INSERT INTO @header EXEC sp_executesql @sql
        SET @sql = 'RESTORE FILELISTONLY FROM DISK=''' + @folder_bak + '\' + @bak_name + ''';'
        INSERT INTO @filelist EXEC sp_executesql @sql
    END TRY
    BEGIN CATCH

        
        PRINT 'Backup ' + @bak_name + ' cannot be restored'

    END CATCH

    IF EXISTS (SELECT * FROM @header) AND EXISTS (SELECT * FROM @filelist)
    BEGIN
    
        SELECT @sql = 'RESTORE DATABASE ' + QUOTENAME(DatabaseName) + ' FROM  DISK = N''' +  @folder_bak + '\' + @bak_name + 
                ''' WITH FILE = 1, NOUNLOAD,  STATS = 5' + 
                (SELECT ', MOVE N''' + QUOTENAME(LogicalName) + 
                        ''' TO N''' + @folder_files + '\' + 
                        SUBSTRING(PhysicalName, LEN(PhysicalName) - CHARINDEX('\', REVERSE(PhysicalName)) + 2, LEN(PhysicalName)) + 
                        '' AS 'data()'
                FROM @filelist
                FOR XML PATH ('')
                )
        FROM @header

        EXEC sp_executesql @sql

    END


    FETCH FROM cur INTO @bak_name
END

CLOSE cur
DEALLOCATE cur


Сообщение было отредактировано: 14 ноя 19, 12:34
14 ноя 19, 12:30    [22016089]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Yasha123
PavelPN,
у вас снова что-то не то с версиями.
если вы на 2017-ый сервер восстанавливаете,
почему в путях MSSQL12.MSSQLSERVER?


Блин, это я дурак. Версию SSMS вместо версии sql server вам назвал.
Версия sql server: Microsoft SQL Server 2014 - 12.0.4100.1 (X64) Apr 20 2015 17:29:27 Copyright (c) Microsoft Corporation Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
14 ноя 19, 12:43    [22016105]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
Minamoto, спасибо. Сегодня попробую всё провернуть в течении дня. По результату отпишу.

В целом, всем спасибо за помощь!!
14 ноя 19, 12:44    [22016108]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PavelPN
Member

Откуда:
Сообщений: 15
komrad, вам тоже спасибо. Не знаю, успею ли я оба потестить скрипта, но на будущее сохраню оба варианта.
14 ноя 19, 12:59    [22016128]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
PavelPN
komrad, вам тоже спасибо. Не знаю, успею ли я оба потестить скрипта, но на будущее сохраню оба варианта.

Оба скрипта (в том числе и мой) , что вам дали не сработают, так как расчет был на 2005 сервер, а у вас оказался 2014.

Чуть позже выложу процу для 2014.
14 ноя 19, 13:02    [22016132]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
PavelPN,

Держите скрипт - с помощью него можно из папки с любым кол-вом bak файлов получить автосгенеренный код на восстановление, который выплюнется этим скриптом. Далее - просто скопировать этот скрипт в новое окно и нажать F5.
Полезно в том, что в одном месте задаете конфигурацию - куда восстанавливать дата-файлы, ку да - логи и это по-сути все. Таким образом с помощью него - можно целые окрцужения накатывать-разворачивать по щелчку пальцев

P.S. этот безумный скрипт писал в свое время человек, который сейчас в Сбербанке Архитектором работает :)

1) Версия для MSSQL 2012 и старше

+
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE WITH OVERRIDE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE  WITH OVERRIDE
GO
DECLARE @srcdir varchar(256)
DECLARE @targetdatadir varchar(256), @targetlogdir varchar(256), @targetftxdir varchar(256)
DECLARE @printSqlOnly bit
DECLARE @addDbName bit
DECLARE @dbnamesuffix varchar(256)

----#######################################################################################

SET @srcdir='D:\123\' -- поменять - исходная папка с bak файлами
SET @targetdatadir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Data\' -- папка для MDF/NDF файлов
SET @targetlogdir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Logs\' --папка для LOG файлов
SET @targetftxdir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Data\' - можно пропустить или указать как папка для MDF/BDF файлов
SET @printSqlOnly=1
SET @addDbName=0
SET @dbnamesuffix=''

----########################################################################################

DECLARE @dircmd varchar(256)
SET @dircmd='dir /b '+@srcdir+'*.bak'

IF object_id('tempdb..#backups') IS NOT NULL DROP TABLE #backups
create table #backups (backupfile varchar(256), stmnt varchar(8000) DEFAULT '')

IF object_id('tempdb..#stmnts') IS NOT NULL DROP TABLE #stmnts
CREATE TABLE #stmnts (RecId int IDENTITY, stmnt varchar(8000) DEFAULT '')

if object_id('tempdb..#databases') is not null drop table #databases
create table #databases 
(BackupName nvarchar(128),
BackupDescription nvarchar(255),
BackupType smallint,
ExpirationDate datetime,
Compressed tinyint,
Position smallint,
DeviceType tinyint,
UserName nvarchar(128),
ServerName nvarchar(128),
DatabaseName nvarchar(128),
DatabaseVersion int,
DatabaseCreationDate datetime,
BackupSize numeric(20,0),
FirstLSN numeric(25,0),
LastLSN numeric(25,0),
CheckpointLSN numeric(25,0),
DatabaseBackupLSN numeric(25,0),
BackupStartDate datetime,
BackupFinishDate datetime,
SortOrder smallint,
CodePage smallint,
UnicodeLocaleId int,
UnicodeComparisonStyle int,
CompatibilityLevel tinyint,
SoftwareVendorId int,
SoftwareVersionMajor int,
SoftwareVersionMinor int,
SoftwareVersionBuild int,
MachineName nvarchar(128),
Flags  int,
BindingID uniqueidentifier,
RecoveryForkID uniqueidentifier,
Collation nvarchar(128),
FamilyGUID uniqueidentifier,
HasBulkLoggedData bit,
IsSnapshot bit,
IsReadOnly bit,
IsSingleUser bit,
HasBackupChecksums bit,
IsDamaged bit,
BeginsLogChain bit,
HasIncompleteMetaData bit,
IsForceOffline bit,
IsCopyOnly bit,
FirstRecoveryForkID uniqueidentifier,
ForkPointLSN numeric(25,0) NULL,
RecoveryModel nvarchar(60),
DifferentialBaseLSN numeric(25,0) NULL,
DifferentialBaseGUID uniqueidentifier,
BackupTypeDescription nvarchar(60),
BackupSetGUID uniqueidentifier NULL,
CompressedBackupSize bigint NULL,
Containment NVARCHAR(MAX),
KeyAlgorithm NVARCHAR(MAX),
EncryptorThumbprint NVARCHAR(MAX),
EncryptorType NVARCHAR(MAX)) 

if object_id('tempdb..#files') is not null drop table #files

create table #files(
LogicalName nvarchar(128),
PhysicalName nvarchar(260),
Type char(1),
FileGroupName nvarchar(128),
Size numeric(20,0),
MaxSize numeric(20,0),
FileID bigint,
CreateLSN numeric(25,0),
DropLSN numeric(25,0) NULL,
UniqueID uniqueidentifier,
ReadOnlyLSN numeric(25,0) NULL,
ReadWriteLSN numeric(25,0) NULL,
BackupSizeInBytes bigint,
SourceBlockSize int,
FileGroupID int,
LogGroupGUID uniqueidentifier NULL,
DifferentialBaseLSN numeric(25,0) NULL,
DifferentialBaseGUID uniqueidentifier,
IsReadOnly bit,
IsPresent bit,
TDEThumbprint varbinary(32)
)

set nocount ON

INSERT INTO #backups (backupfile)
EXEC master.sys.xp_cmdshell @dircmd

DELETE FROM #backups WHERE backupfile IS NULL
UPDATE #backups SET backupfile=@srcdir+backupfile

declare @dbname sysname
declare @backupfile varchar(255), @stmnt varchar(max)
DECLARE @stmntId int
declare cur cursor for select backupfile from #backups

open cur

fetch cur into @backupfile

while @@fetch_status=0
begin
	truncate table #databases
	truncate table #files

	set @stmnt='insert into #databases
	exec(''restore headeronly from disk='''''+@backupfile+''''''')'

	exec(@stmnt)

	set @stmnt='insert into #files
	exec(''restore filelistonly from disk='''''+@backupfile+''''''')'

	exec(@stmnt)

	INSERT INTO #stmnts (stmnt)
	select
'PRINT ''restoring database ['+DatabaseName+@dbnamesuffix+']''
RESTORE DATABASE ['+DatabaseName+@dbnamesuffix+'] FROM  
	DISK = N'''+@backupfile+''' 
	WITH  FILE = 1, 
' from #databases

	select @dbname=''
	if @addDbName=1
	begin
		select top 1 @dbname=DatabaseName+'_' from #databases
	end

	INSERT INTO #stmnts (stmnt)
	select
		'	MOVE N'''+
		LogicalName+
		''' TO N'''+case Type when 'L' then @targetlogdir when 'D' then @targetdatadir when 'F' then @targetftxdir else @targetdatadir end+
		@dbname+LogicalName+'.'+case Type when 'L' then 'ldf' when 'D' then 'mdf' when 'F' then 'FTX' else '' end+''', 
'
	from #files

	INSERT INTO #stmnts (stmnt)
	select
'	NOUNLOAD,  STATS = 1'

	WHILE EXISTS (SELECT TOP 1 1 FROM #stmnts)
	BEGIN
		SELECT TOP 1 @stmntId = RecId, @stmnt = stmnt FROM #stmnts ORDER BY RecId ASC
		UPDATE #backups SET stmnt=stmnt+@stmnt WHERE backupfile=@backupfile
		DELETE FROM #stmnts WHERE RecId=@stmntId
	END 

	fetch cur into @backupfile
end

close cur
deallocate cur

IF @printSqlOnly = 1 SELECT stmnt FROM #backups
ELSE
BEGIN
	SET @stmnt=''
	WHILE EXISTS (SELECT TOP 1 1 FROM #backups)
	BEGIN
		SELECT TOP 1 @backupfile=backupfile, @stmnt=stmnt FROM #backups ORDER BY backupfile ASC
		PRINT '----------------------------------------------------------------------------------------------------'
		PRINT @stmnt
		PRINT '----------------------------------------------------------------------------------------------------'
		EXEC(@stmnt)
		DELETE FROM #backups WHERE backupfile=@backupfile
	END 
END 

set nocount OFF

IF object_id('tempdb..#backups') IS NOT NULL DROP TABLE #backups
IF object_id('tempdb..#stmnts') IS NOT NULL DROP TABLE #stmnts
if object_id('tempdb..#databases') is not null drop table #databases
if object_id('tempdb..#files') is not null drop table #files
GO
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE WITH OVERRIDE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 0
GO
-- To update the currently configured value for this feature.
RECONFIGURE  WITH OVERRIDE
GO


Сообщение было отредактировано: 14 ноя 19, 13:34
14 ноя 19, 13:06    [22016140]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
PsyMisha,

2) Вторая версия генератора на рестор - для MSSQL 2008

+
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE WITH OVERRIDE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE  WITH OVERRIDE
GO
DECLARE @srcdir varchar(256)
DECLARE @targetdatadir varchar(256), @targetlogdir varchar(256), @targetftxdir varchar(256)
DECLARE @printSqlOnly bit
DECLARE @addDbName bit
DECLARE @dbnamesuffix varchar(256)

----#######################################################################################

SET @srcdir='D:\123\' -- поменять - исходная папка с bak файлами
SET @targetdatadir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Data\' -- папка для MDF/NDF файлов
SET @targetlogdir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Logs\' --папка для LOG файлов
SET @targetftxdir='D:\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Data\' -- можно пропустить или указать как папка для MDF/BDF файлов
SET @printSqlOnly=1
SET @addDbName=0
SET @dbnamesuffix=''
----########################################################################################

DECLARE @dircmd varchar(256)
SET @dircmd='dir /b '+@srcdir+'*.bak'

IF object_id('tempdb..#backups') IS NOT NULL DROP TABLE #backups
create table #backups (backupfile varchar(256), stmnt varchar(8000) DEFAULT '')

IF object_id('tempdb..#stmnts') IS NOT NULL DROP TABLE #stmnts
CREATE TABLE #stmnts (RecId int IDENTITY, stmnt varchar(8000) DEFAULT '')

if object_id('tempdb..#databases') is not null drop table #databases
create table #databases 
(BackupName nvarchar(128),
BackupDescription nvarchar(255),
BackupType smallint,
ExpirationDate datetime,
Compressed tinyint,
Position smallint,
DeviceType tinyint,
UserName nvarchar(128),
ServerName nvarchar(128),
DatabaseName nvarchar(128),
DatabaseVersion int,
DatabaseCreationDate datetime,
BackupSize numeric(20,0),
FirstLSN numeric(25,0),
LastLSN numeric(25,0),
CheckpointLSN numeric(25,0),
DatabaseBackupLSN numeric(25,0),
BackupStartDate datetime,
BackupFinishDate datetime,
SortOrder smallint,
CodePage smallint,
UnicodeLocaleId int,
UnicodeComparisonStyle int,
CompatibilityLevel tinyint,
SoftwareVendorId int,
SoftwareVersionMajor int,
SoftwareVersionMinor int,
SoftwareVersionBuild int,
MachineName nvarchar(128),
Flags  int,
BindingID uniqueidentifier,
RecoveryForkID uniqueidentifier,
Collation nvarchar(128),
FamilyGUID uniqueidentifier,
HasBulkLoggedData bit,
IsSnapshot bit,
IsReadOnly bit,
IsSingleUser bit,
HasBackupChecksums bit,
IsDamaged bit,
BeginsLogChain bit,
HasIncompleteMetaData bit,
IsForceOffline bit,
IsCopyOnly bit,
FirstRecoveryForkID uniqueidentifier,
ForkPointLSN numeric(25,0) NULL,
RecoveryModel nvarchar(60),
DifferentialBaseLSN numeric(25,0) NULL,
DifferentialBaseGUID uniqueidentifier,
BackupTypeDescription nvarchar(60),
BackupSetGUID uniqueidentifier NULL,
CompressedBackupSize bigint null)

if object_id('tempdb..#files') is not null drop table #files

create table #files(
LogicalName nvarchar(128),
PhysicalName nvarchar(260),
Type char(1),
FileGroupName nvarchar(128),
Size numeric(20,0),
MaxSize numeric(20,0),
FileID bigint,
CreateLSN numeric(25,0),
DropLSN numeric(25,0) NULL,
UniqueID uniqueidentifier,
ReadOnlyLSN numeric(25,0) NULL,
ReadWriteLSN numeric(25,0) NULL,
BackupSizeInBytes bigint,
SourceBlockSize int,
FileGroupID int,
LogGroupGUID uniqueidentifier NULL,
DifferentialBaseLSN numeric(25,0) NULL,
DifferentialBaseGUID uniqueidentifier,
IsReadOnly bit,
IsPresent bit,
TDEThumbprint varbinary(32)
)

set nocount ON

INSERT INTO #backups (backupfile)
EXEC master.sys.xp_cmdshell @dircmd

DELETE FROM #backups WHERE backupfile IS NULL
UPDATE #backups SET backupfile=@srcdir+backupfile

declare @dbname sysname
declare @backupfile varchar(255), @stmnt varchar(max)
DECLARE @stmntId int
declare cur cursor for select backupfile from #backups

open cur

fetch cur into @backupfile

while @@fetch_status=0
begin
	truncate table #databases
	truncate table #files

	set @stmnt='insert into #databases
	exec(''restore headeronly from disk='''''+@backupfile+''''''')'

	exec(@stmnt)

	set @stmnt='insert into #files
	exec(''restore filelistonly from disk='''''+@backupfile+''''''')'

	exec(@stmnt)

	INSERT INTO #stmnts (stmnt)
	select
'PRINT ''restoring database ['+DatabaseName+@dbnamesuffix+']''
RESTORE DATABASE ['+DatabaseName+@dbnamesuffix+'] FROM  
	DISK = N'''+@backupfile+''' 
	WITH  FILE = 1, 
' from #databases

	select @dbname=''
	if @addDbName=1
	begin
		select top 1 @dbname=DatabaseName+'_' from #databases
	end

	INSERT INTO #stmnts (stmnt)
	select
		'	MOVE N'''+
		LogicalName+
		''' TO N'''+case Type when 'L' then @targetlogdir when 'D' then @targetdatadir when 'F' then @targetftxdir else @targetdatadir end+
		@dbname+LogicalName+'.'+case Type when 'L' then 'ldf' when 'D' then 'mdf' when 'F' then 'FTX' else '' end+''', 
'
	from #files

	INSERT INTO #stmnts (stmnt)
	select
'	NOUNLOAD,  STATS = 5'

	WHILE EXISTS (SELECT TOP 1 1 FROM #stmnts)
	BEGIN
		SELECT TOP 1 @stmntId = RecId, @stmnt = stmnt FROM #stmnts ORDER BY RecId ASC
		UPDATE #backups SET stmnt=stmnt+@stmnt WHERE backupfile=@backupfile
		DELETE FROM #stmnts WHERE RecId=@stmntId
	END 

	fetch cur into @backupfile
end

close cur
deallocate cur

IF @printSqlOnly = 1 SELECT stmnt FROM #backups
ELSE
BEGIN
	SET @stmnt=''
	WHILE EXISTS (SELECT TOP 1 1 FROM #backups)
	BEGIN
		SELECT TOP 1 @backupfile=backupfile, @stmnt=stmnt FROM #backups ORDER BY backupfile ASC
		PRINT '----------------------------------------------------------------------------------------------------'
		PRINT @stmnt
		PRINT '----------------------------------------------------------------------------------------------------'
		EXEC(@stmnt)
		DELETE FROM #backups WHERE backupfile=@backupfile
	END 
END 

set nocount OFF

IF object_id('tempdb..#backups') IS NOT NULL DROP TABLE #backups
IF object_id('tempdb..#stmnts') IS NOT NULL DROP TABLE #stmnts
if object_id('tempdb..#databases') is not null drop table #databases
if object_id('tempdb..#files') is not null drop table #files
GO
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE WITH OVERRIDE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 0
GO
-- To update the currently configured value for this feature.
RECONFIGURE  WITH OVERRIDE
GO


Модератор: Будьте добры упаковывать ваши портяночки в тег spoiler. Спасибо.


Сообщение было отредактировано: 14 ноя 19, 13:35
14 ноя 19, 13:07    [22016141]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
PavelPN
А пока я хочу у себя развернуть территориальные базы, хотя бы для локального доступа к ним. Можете подсказать скрипт как их в автоматическом режиме восстановить? При условии, что некоторые номера почему-то пропущены. Т.е. есть m07.bak, а после него m09.bak
А то все руками поднимать это трата времени, а его не хватает сейчас крайне.

PsyMisha
P.S. этот безумный скрипт писал в свое время человек, который сейчас в Сбербанке Архитектором работает :)
Для одноразовой задачи можно сделать простой запрос, типа
;with num as (select distinct right('0' + convert(varchar, number), 2) as n from master..spt_values where number between 0 and 99)
select '
restore database [flnst01] 
	from disk = N''E:\BackUp\m' + n + '.bak'' with
	move N''flnst_Data'' to N''F:\DATA\flnst' + n + '.mdf'',  
	move N''munst_Log''  to N''F:\DATA\flnst' + n + '_log.ldf''
go
'
from num
order by n


Выполнить в SSMS с выводом результата в текст, потом скопировать и выполнить (предварительно проверив, конечно)
14 ноя 19, 13:18    [22016154]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
alexeyvg,

... а имена датабаз - каждую руками вписывать :)
14 ноя 19, 13:20    [22016161]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
PsyMisha


P.S. этот безумный скрипт писал в свое время человек, который сейчас в Сбербанке Архитектором работает :)

ну, скрипт достаточно простой
заметил, что не обрабатывает следующие моменты:
- целевая база уже существует
- кол-во ее файлов меньше, чем в бекапе
- кол-во бекапов в файле bak больше одного и бекапы разных типов
- не восстанавливается предыдущий владелец базы
- не фиксятся sql юзера
14 ноя 19, 13:30    [22016183]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
komrad

- не восстанавливается предыдущий владелец базы

а с чего бы вдруг его восстанавливать?
у ТС вообще другой сервер,
про старые логины он и вообще не знает
---
щаз запутаем бедного ТС
14 ноя 19, 13:34    [22016194]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1145
komrad
PsyMisha


P.S. этот безумный скрипт писал в свое время человек, который сейчас в Сбербанке Архитектором работает :)

ну, скрипт достаточно простой
заметил, что не обрабатывает следующие моменты:
- целевая база уже существует
- кол-во ее файлов меньше, чем в бекапе
- кол-во бекапов в файле bak больше одного и бекапы разных типов
- не восстанавливается предыдущий владелец базы
- не фиксятся sql юзера


- В папке с бэкапами есть более одного бэкапа для одной базы
- В папке с бэкапами есть разностные бэкапы
- В папке с бэкапами есть не бэкапы с расширением bak

Собственно мой скрипт тоже не обрабатывает эти случаи, за исключением последнего.
Все это можно пофиксить, при желании, если хочется написать максимально универсальный вариант. Но задачи такой не стоит, т.к. обычно это явно работа на один раз для одного конкретного кейса.
14 ноя 19, 13:37    [22016198]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29784
PsyMisha
alexeyvg,

... а имена датабаз - каждую руками вписывать :)
Ну да, там тоже надо написать
restore database [flnst' + n + '] 
14 ноя 19, 13:38    [22016200]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
Yasha123
komrad

- не восстанавливается предыдущий владелец базы

а с чего бы вдруг его восстанавливать?
у ТС вообще другой сервер,
про старые логины он и вообще не знает
---

это отработка ситуации когда восстанавливают базу на тот же сервер и доступ приложению выдан через эккаунт с dbo (нет юзера в базе)
в итоге база восстановлена, владелец - учетка дба, приложение войти в базу не может
такой сетап, конечно, не правильный, но отнюдь не редкий

старые логины - это вариант переноса базы на другой сервер и использование sql учеток (sid не совпадают)

Yasha123

щаз запутаем бедного ТС

нет, путать не будем )
14 ноя 19, 13:42    [22016206]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
Yasha123
Member

Откуда:
Сообщений: 1711
komrad

такой сетап, конечно, не правильный, но отнюдь не редкий

натуральное ССЗБ
14 ноя 19, 14:19    [22016266]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
komrad,

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

USE [Master]
GO

EXEC sp_MSforeachdb 'IF''?'' NOT in (

''tempdb'',
''master'',
''model''
) 

BEGIN
--#######

Use [?];

ALTER USER [JTICORP\USER] WITH LOGIN = [JTICORP\USER]

--#######
END'
14 ноя 19, 14:35    [22016296]     Ответить | Цитировать Сообщить модератору
 Re: Восстановление БД из нескольких .bak  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 544
PsyMisha,
Чекнуть, какие именно юзеры в базах остались без логина - непримаплены - orphaned - можно так же массовым курсором

IF OBJECT_ID('tempdb..#MyTempTable_Logins') IS NOT NULL  
DROP TABLE #MyTempTable_Logins

CREATE TABLE #MyTempTable_Logins
(
[Current_Database_Name] NVARCHAR(MAX),
[Database_User_Name] NVARCHAR(MAX),
[Login_Name] NVARCHAR(MAX),
[Type] NVARCHAR(MAX),
[SID] VARBINARY(MAX),
[Default_Database] VARCHAR(MAX),
[Is_Disabled] BIT
)

--#######
INSERT INTO #MyTempTable_Logins
EXEC sp_MsForEachDB @command1 = '

USE [?]

SELECT
DB_NAME() AS ''Current_Database_Name'',
UPPER(DBP.name) AS ''Database_User_Name'',
UPPER(SP.name) AS ''Login_Name'',
DBP.type_desc AS ''Type'',
SP.[sid],
UPPER(SP.default_database_name) AS ''Default_Database'',
ISNULL(SP.is_disabled, 0) AS ''Is_Disabled''

FROM sys.database_principals AS DBP
LEFT JOIN sys.server_principals AS SP ON SP.[sid] = DBP.[sid]

WHERE 
DBP.type_desc NOT IN (''DATABASE_ROLE'') AND DBP.name NOT IN (''INFORMATION_SCHEMA'', ''sys'', ''guest'', ''dbo'')
--#######
'

SELECT *
FROM #MyTempTable_Logins
WHERE Login_Name IS NULL

ORDER BY 1, 2


SELECT DISTINCT  database_user_name
FROM #MyTempTable_Logins
WHERE Login_Name IS NULL


Сообщение было отредактировано: 14 ноя 19, 14:43
14 ноя 19, 14:41    [22016309]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2 3      [все]
Все форумы / Microsoft SQL Server Ответить