Обращайте внимание на права в базе при переходе с SQL 2000 на 2005
Предыстория
Сегодня я разгадал одну «тайну», которая ведет к потере данных. Но давайте начнем с самого начала…
Недавно мы обновляли железо и SQL Server до 2005-й x64 версии. Все прошло без проблем, т.к. мы используем SAN, а перенос базы сделали с помощью Detach/attach, ну и одно задание SSIS для переноса учетных записей. Все ОК. После апгрейда все работает без проблем. Но…
Некоторые пользователи начали жаловаться, что часть функций работает неправильно. Что же происходит?
Находясь в карточной форме, вы можете нажатием кнопки открыть другую форму. В этой новой форме отображаются связанные записи, а если их нет, они создаются. Вот так просто. Но теперь, когда пользователь открывает форму, в ней ничего нет. Я проводил тестирование — все работало на ура, записи создавались. Так, тут есть над чем подумать и кое-что разгадать.
После нескольких итераций типа «ты попробуй, я попробую» мы заметили, что когда пользователь открывает форму, в ней всего одна строка, похожая на уже вставленную (т.е. БЕЗ звездочки в левой части таблицы). Но после того, как мы двигали курсор (или даже открывали/закрывали список фильтров), запись исчезала, а мы – на новой строке.
Код выглядит правильно, нет никаких условий или чего-нибудь еще, препятствующего процессу добавления записи. Я запустил client monitor, там есть все команды вставки записей, но в таблице по-прежнему ничего нет.
Не буду углубляться в анализ проблемы, в общем, перепрыгнем на тот момент, когда я обнаружил, в чем дело.
Как всегда, отыскать проблему помог SQL Profiler. Я запустил в профайлере трассировку серверных ошибок и исключений, и как только воспроизвел свою ошибку, уведил несколько красных строк, в которых говорилось следующее:
USER Error Message 74 SHOWPLAN permission denied IN DATABASE 'blablabla'.
Это подтвердило одну вещь, которую я заметил в самом начале – с правами db_owner все работает. Проблемы начинаются, если вы не dbo. После того как я заглянул в права и сравнил права перемещенной базы с правами базы, СОЗДАННОЙ на SQL 2005, то обнаружил, что для роли $ndo$shadow не хватает прав на «Show Plan» и «References».
Итоги
Почему же их там нет? Потому что на MS SQL 2000 они отсутствуют в принципе. Они прописываются в момент, когда вы создаете новую БД на MS SQL 2005, но при переносе базы с помощью Detach/Attach или Backup/Restore – нет. Они не создаются даже тогда, когда из NAV запускается процесс «Synchronize All» (естественно, Security Model должна быть Standard).
Кроме того, я заметил, что это баг проявляется, только если вы работаете с окнами NAV, развернутыми на весь экран. Если вы работаете с окнами нормального размера, все, похоже, работает правильно.
Выводы
После перехода с MS SQL 2000 на MS SQL 2005, если вы НЕ СОЗДАЕТЕ новую БД, а используете Detach/Attach или Backup/Restore функции сервера для переноса БД, необходимо:
Дать роли $ndo$shadow права на «Show Plan» и «References».
Не забудьте об этом, иначе сможете лицезреть «таинственные» исчезновения данных, и поведение системы.
Ошибка – подробно
- Данные создаются в триггере OnRun во второй форме.
- После того, как отработал триггер, в первой форме стартует обновление, т.к. вызывается триггер OnAfterGetCurrRecord первой формы, а там есть команда CurrForm.UPDATECONTROLS.
- Т.к. этот процесс все еще выполняется в транзакции, начатой в триггере OnRun второй формы, и т.к. в нем присутствуют команды SHOW PLAN, и т.к. прав на SHOW PLAN у роли нет, SQL сервер генерит исключение «Доступ запрещен» (permission denied) и транзация откатывается.
- Клиент NAV не отлавливает данное исключение – в этом корень проблемы.
- Процесс обновления первой формы не запускается, если окно не раскрыто на полный экран.
- Исключение с правами генерится каждый раз, когда формы неявно вызывают COUNTAPPROX для определения примерного количества записей (для перерисовки скролбаров?) и все эти вызовы отменяются.
- Пользовать знать-не знает об этих ошибках с правами…
Это достаточно редкий баг, но проблемы с правами могут стать причиной другого бага, который не так легко отловить или даже заметить.
Шаги по воспроизведению ошибки
- Создайте новую БД на MS SQL 2005, восстановите в нее БД Кронуса.
- Удалите права на “Show Plan” для роли $ndo$shadow (или можете сделать по-другому: сделать детач какой-нибудь демо-базы на SQL 2000, и прицепить ее на SQL 2005 – права в этом случае не перенесутся, т.к. на SQL 2000 таких прав просто не существует).
- Импортируйте в базу приложенные объекты.
- Запустите форму 90001, раскройте ее на полный экран (баг наблюдается с раскрытыми на весь экран окнами).
- Нажмите «Test – Run Form».
- Откроется второе окно (также на весь экран), но в не будет записей (или одна, до тех пор пока вы не откройте окошко с фильтрами, или подвигаете курсор – после этого строки пропадают).
- Сверните окно до обычного размера, закройте окно из пункта 6.
- В окне обычного размера (не на весь экран) снова нажмите «Test – Run Form».
- Второе окно снова откроется, но уже с введенными записями – т.е. на этот раз правильно.
Приложение: COMMIT BUG repro.ZIP
Заметка – вольный перевод статьи Камила Сачека «Pay attention to permissions when upgrading DB from SQL 2000 to SQL 2005»

Автор: Андрей Стрельников
В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.
Количество статей, опубликованных автором: 86.