Переход на SQL Server 2008 с предыдущих версий

В этой статье в BOL приводится детальная картина, какие версии и редакции на какие 2008-й версии можно апгрейдить. Если абстрагироваться от редакций и говорить проще, то под предыдущими версиями понимаются 2000 и 2005. Если у кого-то до сих пор трудится семерка или 6.х, снимаю шляпу, но прямого апгрейда не получится. Нужно будет сначала перейти на 2000 и, не задерживаясь, с него на 2008-й. Покупать специально для этого 2000-й, естественно, не надо; достаточно 2000 Evaluation Edition, правда, где ее сейчас взять, я не представляю. Если вдруг действительно понадобится, пишите, будем искать, а здесь и далее под словом апгрейд будет пониматься апгрейд с 2005/2000.

Как и в большинстве аналогичных ситуаций, существует два подхода к апгрейду на SQL Server 2008, которые по науке называются Upgrade In-Place (замещение) и Upgrade Side-by-side (параллельная установка). Первый способ заключается в том, что мы запускаем сетап 2008-го там же, где стоит 2005/2000 и, когда сетап обнаружит это и спросит, не хотим ли мы проапгрейдиться, указать ему имя экземпляра предыдущей версии. Это очень удобный, практически на 100% автоматический процесс, включая кластерные экземпляры. Неудобство состоит в том, что старый экземпляр перекрывается новым, и если после перехода вылезет что-то незапланированное, откатиться назад будет проблематично. Чтобы подстелить соломку, в большинстве критических приложений используется второй подход, когда рядом ставится новый экземпляр SQL Server 2008. Перенести на него данные с экземпляра предыдущей версии можно массой способов: Copy Database Wizard, скрипты T-SQL, bcp и т.д. Наиболее распространенными являются детач/аттач базы или ее бэкап/рестор.

 

Пример переноса базы детачем на 2005-м и аттачем на 2008-м.

--На 2005-м:

use tempdb

alter database AdventureWorks_2005 set read_only with rollback immediate

exec sp_detach_db @dbname = 'AdventureWorks_2005'

--Копируем файлы БД, иначе при аттаче их займет 2008-й и 2005-й не сможет их зацепить обратно.

--2008-й, кстати, их проапгрейдит автоматом, так что 2005-й обратно уже не примет.

exec sp_configure 'show advanced options', 1

reconfigure with override

exec sp_configure 'xp_cmdshell', 1

reconfigure with override

exec xp_cmdshell 'copy "C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks2005_Data.mdf" "C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA"'

exec xp_cmdshell 'copy "C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks2005_Log.ldf" "C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA"'

--На 2008-м:

use tempdb

if exists (select 1 from sys.databases where name = 'AdventureWorks_2005') begin

 alter database AdventureWorks_2005 set single_user with rollback immediate

 drop database AdventureWorks_2005

end

create database AdventureWorks_2005 on primary

(filename = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\AdventureWorks2005_Data.mdf')

log on

(filename = 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\AdventureWorks2005_Log.ldf')

for attach

--Или

exec sp_attach_db @dbname = 'AdventureWorks_2005',

    @filename1 = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks2005_Data.mdf',

    @filename2 = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks2005_Log.ldf'

--что является обсолитной конструкцией.

Скрипт 1

Пример переноса базы восстановлением на 2008-м резервной копии, сделанной на 2005-м.

--На 2005-м:

use tempdb

alter database AdventureWorks_2005 set read_only with rollback immediate

backup database AdventureWorks_2005 to disk = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\AdventureWorks_2005.bak'

with init, stats = 10, name = 'Полный бэкап', description = 'Для апгрейда на 2008'

--На 2008-м:

use tempdb

--Проверяем на фсякей содержание бэкапа

restore headeronly from disk = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\AdventureWorks_2005.bak'

restore filelistonly from disk = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\AdventureWorks_2005.bak' with file = 1

--И восстанавливаемся из него

restore database AdventureWorks_2005 from disk = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\AdventureWorks_2005.bak'

with

move 'AdventureWorks_Data' to 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\AdventureWorks_2005.mdf',

move 'AdventureWorks_Log' to 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\AdventureWorks_2005.ldf',

recovery, stats = 10, replace

alter database AdventureWorks_2005 set read_write

use AdventureWorks_2005

--Перестройка индексов, апдейт статистики и перевод базы в режим поддержки новой версии

exec sp_MSforeachtable @command1 = "print '?'", @command2 = 'alter index all on ? rebuild with (online = on)'

exec sp_updatestats

alter database AdventureWorks_2005 set compatibility_level = 100

Скрипт 2

Комментарии:

- Обратное неверно, т.е. оба способа прекрасно работают в направлении 2005/2000 -> 2008, но переехать назад при помощи них нельзя.

- Дополнительно требуется обеспечить перенос необходимых логинов, на которые отображаются пользователи базы. Логины являются объектами уровня сервера, поэтому вместе с базой они автоматически не перенесутся. Их можно заскриптовать отдельно на источнике и выполнить скрипт на назначении, можно воспользоваться Transfer Logins Task в SSIS. В случае интегрированной безопасности окружение назначения должно уже иметь соответствующие записи в AD.

Осиротевшие SQLные юзеры базы лечатся при помощи sp_change_users_login (к-я явл-ся deprecated ;))

- Detach/attach и backup/restore можно выполнить из графического интерфейса SSMS, однако буквы копировать в блог проще, чем картинки, поэтому гуевый способ предоставляется в качестве самостоятельного упражнения.

В любом случае формально переехать на 2008-й - не проблема. Проблем я здесь вижу три:

- Избавиться от несовместимостей в коде. В зависимости от типа несовместимости это может быть какая-то синтаксическая конструкция языка, которая работала на предыдущей версии, но не поддерживается в 2008-м (их немного, но они есть); это может быть конструкция, которая пока работает, но не будет поддерживаться в следующей версии; наконец, это может быть конструкция, которая работает, однако появился способ сделать это более оптимально. Понятно, что несовместимости первого типа нужно вычислить еще до переноса, иначе приложение просто не окажется неработоспособно.

- Обеспечить синхронизацию с базой, оставшейся на предыдущей версии, чтобы она поддерживалась в актуальном состоянии и на нее можно было вернуться по желанию в любой момент. Синхронизация, как правило, обеспечивается при помощи репликации. Это могут быть как штатные механизмы репликации SQL Server, так и самописные, как передающие снэпшоты в случае небольших таблиц, так и отслеживающие изменения на 2008-м (Change Data Capture, Change Tracking, свое) и доставляющие их по расписанию на 2005-й. Еще в C:\Program Files\Microsoft SQL Server\100\COM имеется тула tablediff.exe, позволяющая отслеживать и синхронизировать изменения между таблицами.

- Тупой перенос базы не есть апгрейд. Приложение должно использовать новые возможности SQL Server 2008, чтобы решать более сложные задачи или прежние, но лучше, более эффективно. Для этого нужно четко понимать, что нового и в каких областях предлагает новая версия и представлять, как приложение сможет от этого выиграть. Иначе для чего затевать апгрейд?