Рейтинг:4

Можно ли временно отключить изменения базы данных в Microsoft SQL Server?

флаг ru

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

Есть ли хороший способ отключить INSERTS и UPDATES, но разрешить SELECTS в базе данных?

Или мне нужно заблокировать изменения на бизнес-уровне/отключить базу данных, пока происходит обновление?

joeqwerty avatar
флаг cv
Вы можете перевести базу данных в режим только для чтения, но я понятия не имею, какое влияние это окажет на ваше приложение и не помешает ли вам вносить обновления/изменения.
Sir Swears-a-lot avatar
флаг cw
Это может помочь, если вы можете уточнить. 1. Возможен/приемлем ли сбой? Если так, то как долго? Насколько велика БД? Сколько ГБ? Сколько столов? Сколько вставок/обновлений вы ожидаете в час?
Sir Swears-a-lot avatar
флаг cw
Какая у вас версия SQL? Для какой сортировки установлен ваш db? Вы буквально собираетесь преобразовать параметры сортировки столбцов? Или вы просто переходите с nvarchar на varchar?
Sir Swears-a-lot avatar
флаг cw
Почему вы переходите на UTF8?
флаг cn
@SirSwears-a-lot: UTF8 лучше подходит для многих потребителей данных. Аналогично использованию datetime2 вместо datetime. Для больших объемов данных в типичной западной кодировке это экономит память, поскольку большинство символов представлены всего восемью битами. https://techcommunity.microsoft.com/t5/sql-server/introduction-utf-8-support-for-sql-server/ba-p/734928
флаг ru
@SirSwears-a-lot в моем случае, это потому, что я был вынужден полностью перепроектировать, какое приложение читает из базы данных, что включает в себя переключение с библиотеки, которая только читает/записывает utf16, на библиотеку, которая только читает/записывает utf8.
Рейтинг:17
флаг cn

У вас может быть XY-проблема. Существуют способы сделать то, что вы пытаетесь сделать, не требуя, чтобы обрабатываемые таблицы были недоступны для изменения на время операции. Вот как бы я его качал (высокий уровень):

  1. Добавьте новый столбец с нужным определением (тип данных, сопоставление и т. д.).
  2. Используйте триггеры «после вставки», чтобы убедиться, что изменения данных, поступающие из вашего приложения, также изменяют новый столбец.
  3. Заполните существующие данные в таблице.
  4. Удалите старый столбец, переименуйте новый столбец, чтобы он имел имя старого столбца.
Sir Swears-a-lot avatar
флаг cw
XY-проблема. О боже как красиво. чуть не заплакал... ;)
Рейтинг:7
флаг in

Без дополнительных знаний о вашей схеме базы данных, разрешениях и т. д. и некоторого представления о вашей стратегии в отношении вашего приложения чрезвычайно трудно давать предписания. Как минимум, позволяет ли приложение работать в режиме только для чтения с заблокированными обновлениями таблицы?

На самом базовом уровне "Да" вы можете это сделать... DENY INSERT, UPDATE, DELETE ON <table> TO <user> однако невозможно сказать, как отреагирует ваше приложение. По моему опыту, большинство приложений будут разбрызгивать ошибки повсюду и кричать о кровавом убийстве, если вы сделаете это, возможно, даже повредив данные (непроверенные ошибки, плохое использование транзакций и т. д.). Редко (возможно, никогда) я не видел приложения, которое изящно переключалось в режим только для чтения, когда доступ к базе данных был не таким, как планировалось/ожидалось.

Так что ТЕСТ! Тестируйте, тестируйте, тестируйте в контролируемой непроизводственной среде, пока у вас не будет документированного процесса, поддерживающего ваши изменения.

Если ваши требования не допускают длительного простоя (или вообще не допускают отключения), существуют более сложные способы справиться с этим. Одной из мыслей было бы добавить триггер после вставки/после обновления для автоматического преобразования новых/обновленных записей в новое поле во время обслуживания небольших пакетов. Как только все данные будут преобразованы, переключите приложение на новое поле и удалите старое.

dave_thompson_085 avatar
флаг jp
По иронии судьбы, сам Stack несколько раз в год проводит тестирование или эксперименты, которые делают (соответствующую) базу данных доступной только для чтения в течение умеренного периода, например получаса, и, насколько я заметил (извне), они делают это довольно чисто: заметное, но не неприятное желтое поле в верхней части каждой страницы, сообщающее о статусе, и интерактивные элементы, которые требуют написания, отключены.
Doug avatar
флаг in
Да, но магия в том, как они это делают. Я видел много приложений, в которых есть кнопка конфигурации для остановки обновлений, однако она действительно доступна только для чтения на уровне приложения, а не в базе данных. т.е. приложение перестает разрешать пользователям изменять записи, но на самом деле приложение все еще может записывать в базу данных. Сложная система (StackExchange) будет иметь сложный переключатель уровня приложения только для чтения. Насколько я помню, я никогда не видел приложения, которое изящно переключалось бы в режим только для чтения, когда оно ожидало, но отказывало в записи на уровне базы данных.
Рейтинг:0
флаг cw

Помимо UTF-8 и UTF-16, я думаю, что более важный вопрос, который вы задаете, заключается в том, как развернуть изменения в производственной системе с минимальным временем простоя. Я уверен, что есть несколько разных способов, но я бы подошел к этому так.

  1. Создайте копию своей базы данных.
  2. Запустите обновления схемы на копии.
  3. Используйте такой продукт, как Redgate SQL Compare, или напишите свои собственные скрипты для синхронизации данных. Собери их как можно ближе
  4. Закройте приложение, повторная синхронизация.
  5. Измените подключение к базе данных на новую базу данных (или переименуйте базы данных).
  6. Перезапустите приложение.

Я знаю, что это звучит упрощенно и может быть невозможно по ряду причин, но это стоило бы исследовать.

Я хотел бы сделать это по нескольким причинам. Минимальные простои и влияние на пользователей. Возможность безопасного отката. Возможность проверить влияние изменений схемы/данных.

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

флаг sn
Что такое *"Redgate SQL"*? Часть *Redgate Data Tools*? *Ядро ReadyRoll*? *Ядро подсказки SQL*? *Поиск SQL*? Что-то другое?
Sir Swears-a-lot avatar
флаг cw
@PeterMortensen Мои извинения. «Сравнение Redgate SQL» можно использовать для синхронизации баз данных.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.