SQL Server, jak obejść wypełnianie dziennika transakcji podczas aktualizowania kolumny do int

18

Mam wywołaną tabelę SQL Server 2005 BRITTNEY_SPEARS_MARRIAGESi ma ona następujące kolumny:

MarrigeId tinyint, 
HusbandName varchar(500),
MarrigeLength int

Teraz mam inny stolik BRITTNEY_SPEARS_MARRIAGE_STORIES

StoryId int, 
MarriageId tinyint, 
StoryText nvarchar(max)

Problem polega na tym, że chcemy zaktualizować MarrigeIdkolumnę do intz tinyint. Po prostu czujemy, że Brittney będzie miał dużo małżeństw, zanim wszystko zostanie powiedziane i zrobione.

Teraz BRITTNEY_SPEARS_MARRIAGE_STORIEStabela ma 18 milionów wierszy (hej, dziewczyna ma pewne problemy), więc kiedy idziemy na aktualizację, dziennik transakcji zapełnia się i nasze okno SQL Server umiera.

Jak możemy to obejść?

Czy w ogóle można powiedzieć „Hej, SQL Server, zaktualizuję tę kolumnę i powiększę ją. Zaufaj mi na tym serwerze SQL. Proszę nie wypełniać dziennika transakcji podczas próby sprawdzenia wszystkiego?”

codingguy3000
źródło

Odpowiedzi:

7

Nie ma sposobu, aby powiedzieć SQL Serverowi, aby nie korzystał z dziennika transakcji.

Co można zrobić, to ustawić modelu odzyskiwania bazy danych do prostych, które będą nadpisywać stare wpisy dziennika jako pamięć jest potrzebna. Nie powinieneś jednak tego robić na serwerze produkcyjnym, ponieważ nie będziesz w stanie wykonać niektórych rodzajów przywracania, takich jak przywracanie do określonego momentu.

Ewentualnie możesz ustawić większy rozmiar pliku dziennika transakcji - jako nienaukową zasadę upewnię się, że albo A) twój dziennik transakcji ma co najmniej około 1,5x więcej wolnego miejsca niż rozmiar stołu lub B) że dziennik transakcji może automatycznie wyrosnąć na dysk, który ma co najmniej tyle wolnej przestrzeni dyskowej.

Możesz zwolnić miejsce w dzienniku transakcji, wykonując kopię zapasową dziennika. Jeśli nie zależy ci na zawartości dziennika, wyrzuć plik. Skrót do tego jest BACKUP LOG <Your Database Name> TO DISK = 'NUL:'. Ponownie, nie rób tego na serwerze produkcyjnym, chyba że masz absolutną pewność, że rozumiesz implikacje.

Kolejną rzeczą, na którą należy uważać (choć nie jest to całkowicie związane z pytaniem), jest upewnienie się, że tabela, którą rozwijasz, ma zdefiniowany indeks klastrowany. Jeśli tego nie zrobi, tabela może spowodować bardzo dużą fragmentację sterty i potencjalnie może stać się niepotrzebnie duża przy takiej zmianie.

Dave Markle
źródło
5
  • Upuść wszelkie klucze obce
  • Utwórz nowe tabele za pomocą intzamiasttinyint
  • Przenieś wiersze na partię 1000 (wstaw je do nowej tabeli, usuń je ze starej)
  • Upuść stare stoły
  • Zmień nazwy nowych tabel na stare nazwy, używając sp_rename
  • Odtwórz klucze obce

pS Jeśli Twój dziennik transakcji jest duży ... sprawdź model odzyskiwania. Jeśli model odzyskiwania nie jest simple, jak długo trwało od ostatniego utworzenia kopii zapasowej dziennika?

Andomar
źródło
Masz na myśli, że skoro wykonałeś kopię zapasową dziennika, wykonanie kopii zapasowej bazy danych nie zmniejszy dziennika.
HLGEM
@HLGEM: Masz rację, właśnie przeczytałem artykuł Paula Randala na ten temat. Nieoczekiwanie jednak, jeśli wykonasz tylko pełne kopie zapasowe, Twój dziennik będzie się powiększał.
Andomar