W jaki sposób można śledzić zmiany w bazie danych w kontroli źródła?




Używamy SQL Server 2000/2005 oraz Vault lub SVN na większość naszych projektów. Nie znalazłem godnej roztwór do przechwytywania zmian w bazie schematu / proc w obu systemach kontroli źródła.


Nasze obecne rozwiązanie jest dość kłopotliwe i trudne do wyegzekwowania (skrypt się obiekt, który zmienia i zobowiązać go do bazy danych).


Mamy wiele pomysłów, jak rozwiązać ten problem z jakimś niestandardowym rozwoju, ale wolałbym zainstalować istniejącego narzędzia (płatne narzędzia są w porządku).


Tak: jak można śledzić zmiany kodu bazy danych? Czy masz jakieś zalecanych narzędzi?







**Edytować:**


Dzięki za wszystkie sugestie. Ze względu na ograniczenia czasowe, ja raczej nie toczą tu moje własne. I większość sugestii mają wadę, że wymagają one dev przestrzegać pewnych procedur.


Zamiast idealnym rozwiązaniem byłoby monitorowanie bazy danych SQL dla zmian i popełnić żadnych wykrytych zmian w SCM. Na przykład, jeśli SQL Server miał dodatek, który może nagrywać żadnych zmian DML z użytkownikiem że dokonane zmiany, a następnie popełnić skrypt tego obiektu do SCM, byłbym zachwycony.


Rozmawialiśmy wewnętrznie około dwóch systemach: 1. W SQL 2005, należy użyć obiektu, aby ograniczyć uprawnienia cię od zmiany przedmiotu dopóki nie zrobił „Zamówienie”. Następnie procedura zameldowania by skrypt go do SCM. 2. Uruchom zaplanowane zadanie wykryć wszelkie zmiany i zobowiązać je (anonimowo) do SCM.


Byłoby miło, gdybym mógł pominąć część działań użytkownika i mają system obsługi to wszystko automatycznie.
Użyj edycję programu Visual Studio do bazy danych skryptu z bazą danych. Działa jak czar i można użyć dowolnego systemu kontroli źródła, oczywiście najlepiej, jeśli ma wtyczek VS. Narzędzie posiada również szereg innych przydatnych funkcji. Sprawdź je tutaj, w tym wielkim poście


<http://www.vitalygorn.com/blog/post/2008/01/Handling-Database-easily-with-Visual-Studio-2008.aspx>


lub sprawdzić MSDN dla oficjalnej dokumentacji
<p>w witrynach, w których pracowałem, wszelkie zmiany, które należy wprowadzić w instancjach produkcyjnych, muszą być skryptowane jako skrypty zmian, które będą działać w sql * plus; ponadto skrypty potrzebne do odtworzenia od podstaw wszystkich obiektów schematu muszą być aktualizowane. wszystkie te skrypty są sprawdzane pod kątem kontroli zmian i stamtąd migrowane.</p><p>możesz kontrolować zmiany ddl lub używać wyzwalaczy ddl, aby wykrywać zmiany, a nawet używać oprogramowania różnicowego do porównywania dwóch wystąpień, ale metody te są niedyskryminujące; często programista wprowadza i cofa wiele zmian w schemacie (np. małe zmiany testowe, tworzenie fałszywych tabel do testowania koncepcji itp.) przed ustaleniem, co dokładnie należy zmienić.</p> <p>użycie sql server profiler (narzędzie gui) do śledzenia serwera produkcyjnego nie jest dobrym pomysłem. ale to zależy od obciążenia. zamiast tego należy używać śledzenia sql po stronie serwera (patrz <a href="http://msdn.microsoft.com/en-us/library/ms188662%28v=sql.100%29.aspx">sp\_trace\_xxx</a> procedury). znalazłem również artykuły:</p><p> <a href="http://sqlblog.com/blogs/linchi\_shea/archive/2007/08/01/trace-profiler-test.aspx">wpływ na wydajność: śledzenie profilera vs. śledzenie sql po stronie serwera</a> ,</p><p> <a href="http://vyaskn.tripod.com/server\_side\_tracing\_in\_sql\_server.htm">automatyzacja śledzenia po stronie serwera w programie sql server</a> </p><p> <a href="http://weblogs.sqlteam.com/dang/archive/2007/12/16/avoid-causing-problems-with-profiler.aspx">nikaj powodowania problemów z profiler</a> </p><p>może będzie zainteresowany i przydatny.</p><p> <a href="http://msdn.microsoft.com/en-us/library/ms187023.aspx">rezerwuj online</a> mówi:</p><ul> <li>uruchom profiler zdalnie zamiast bezpośrednio na serwerze</li> <li>unikaj włączania zdarzeń, które występują często (np. zablokuj: nabyte), chyba że jest to absolutnie konieczne</li> <li>uwzględnij tylko potrzebne klasy zdarzeń</li> <li>określ filtry ograniczające, aby zmniejszyć liczbę zdarzeń</li> <li>unikaj zbędnych danych (np. sql: batchstarting i sql: batchcompleted)</li> <li>unikaj uruchamiania dużych śladów za pomocą profiler; zamiast tego rozważ śledzenie sql po stronie serwera</li> <li>ogranicz rozmiar pliku śledzenia po stronie serwera i zarządzaj wykorzystaniem miejsca</li> </ul> <p>masz tutaj kilka różnych pytań, więc wybiję je indywidualnie:</p><p><strong>„przeczytałem, że najlepszą praktyką jest nie zezwalanie użytkownikom na bezpośrednie logowanie się do sa, zamiast używania uwierzytelniania systemu windows”</strong></p><p>mieszasz tutaj dwie rzeczy: koncepcję sa oraz koncepcję uwierzytelnienia sql i windows.</p><p>uwierzytelnianie sql to lista nazw użytkowników i haseł przechowywanych na każdym serwerze sql. pierwszym problemem jest fakt, że jest przechowywany w sql. jeśli musisz zmienić hasło logowania, musisz je zmienić na każdym serwerze (lub utrzymywać różne hasła na różnych serwerach). dzięki uwierzytelnianiu systemu windows można centralnie wyłączać logowanie, zmieniać hasła, ustawiać zasady itp.</p><p>jeśli zdecydujesz się na uwierzytelnianie sql, sa to tylko jeden login do uwierzytelnienia sql. jest to domyślna nazwa użytkownika administratora, podobnie jak administrator w uwierzytelnianiu systemu windows. ma lokalne supermoce w tej jednej instancji, ale nie globalne supermocarstwa we wszystkich instancjach.</p><p><strong>„... i zezwalanie tym kontom (lub grupom kont) na uprawnienia administratora.”</strong></p><p>niezależnie od wybranej metody uwierzytelniania, najlepiej postępować zgodnie z zasadą najmniejszego uprzywilejowania: przyznać ludziom minimalne prawa, których potrzebują do wykonania swojej pracy, i nie więcej.</p><p>nie myśl o nich jak o zwykłym logowaniu - to ludzie, którzy mogą cię zwolnić. jeśli upuszczą bazę danych lub przypadkowo wyłączą zadania tworzenia kopii zapasowych, nie zostaną zwolnieni, ponieważ domyślnie sql nie śledzi, kto co zrobił. to ty zostaniesz zwolniony, bo tak się stanie i nie będziesz w stanie powiedzieć, która osoba to zrobiła.</p><p><strong>„w jaki sposób najlepsza praktyka zwiększa bezpieczeństwo moich wystąpień sql server?”</strong></p><p>chcesz zrobić dwie rzeczy:</p><ol> <li>powstrzymaj ludzi przed zerwaniem serwera</li> <li>gdy zepsują serwer, być w stanie dokładnie określić, kto to zrobił</li> </ol><p>pierwszy realizowany jest zgodnie z zasadą najmniejszego przywileju: dawanie ludziom tylko potrzebnych im uprawnień i nic więcej.</p><p>druga realizowana jest poprzez nadanie każdej osobie własnego loginu, nie zezwalanie na wspólne logowanie (np. zezwalanie każdemu na używanie tej samej nazwy użytkownika/hasła), a najlepiej na kontrolę logowań. prawdopodobnie nie zrobisz tej ostatniej części od razu, ponieważ jest to trochę bolesne, ale odłóżmy elementy na miejsce, abyś mógł dodać audyt później, gdy ktoś upuści bazę danych, a twój szef chce wiedzieć, dlaczego.</p><p>wiem, co myślisz: „ale kodujemy aplikacje, a aplikacja wymaga logowania”. tak, nadaj aplikacji swój własny login, a programiści muszą znać to hasło, ale login powinien być tak pozbawiony uprawnień, że nikt przy zdrowych zmysłach nie chciałby z niego korzystać. na przykład może być konieczne, aby był w rolach db\_datareader i db\_datawriter, nic więcej. w ten sposób może wstawiać, aktualizować, usuwać i wybierać dane, ale niekoniecznie zmieniać schematy, dodawać indeksy, zmieniać procedury składowane itp.</p><p><strong>„czy dotyczy to tylko instancji produkcyjnych, czy też naszych wewnętrznych instancji programistycznych?”</strong></p><p>myślę, że dotyczy to również instancji programistycznych, ponieważ zwykle martwię się, że ludzie coś zepsują. ludzie po prostu lubią łamać serwery podczas programowania. i oczywiście, kiedy nadszedł czas na spakowanie listy zmian do migracji do produkcji, muszę wiedzieć, czy konkretny indeks jest naprawdę niezbędny dla aplikacji, czy też jakiś głupek właśnie uruchomił doradcę dostrajania bazy danych i powiedział, aby zastosować wszystkie zmiany . odpowiednie uprawnienia pomagają zmniejszyć ten ból.</p> Często jest to realizowane za pomocą [„Data Driven Subskrypcje”](https://msdn.microsoft.com/en-us/library/ms169673.aspx) , ale ta funkcja jest dostępna tylko w niektórych wersjach SQL: Enterprise i Business Intelligence, ale nie w standardzie.


Tak więc istnieje wiele twórczych obejścia. Ale nie lubię żadnego z nich, a wszystko to wymaga uczciwej trochę pracy poza SSRS.


Do obejścia widziałem to: Tworzenie subskrypcji, a następnie wyłączenie lub włączenie zadanie SQL, który wysyła subskrypcję (zidentyfikowanego przez GUID).


Tworzenie .exe .NET otoki do obsługi wysyłania wiadomości e-mail. Można go uruchomić kwerendę najpierw sprawdzić, ile zwracane są wiersze, a następnie w razie potrzeby wygenerować raport i umieścić go w wiadomości e-mail. <p>oprócz innych odpowiedzi ...</p><p> <a href="https://dba.stackexchange.com/questions/1677/is-there-any-good-tool-for-making-database-design-and-prototypes/1678#1678">najpierw przechwytywanie modelu koncepcyjnego</a> powinno określać zakres i wymagania. na tej podstawie możesz uzyskać logiczne i fizyczne modele danych.</p><p>gdy jest to w większości statyczne, masz stabilną bazę danych, na której można zbudować aplikację. jest to sprzeczne z pierwszą opcją.</p><p>twój drugi punkt zakończy się brudną, niemożliwą do utrzymania <em> kulą błota </em>. model danych nigdy nie zostanie naprawiony: jeśli nie zaprojektowałeś go z góry, nie będziesz miał czasu, aby go naprawić przed wysyłką. będziesz zbyt zajęty hakowaniem rzeczy razem.</p><p>nastąpią niewielkie zmiany w schemacie, łączenie lub dzielenie tabel, zmiana relacji itp., ale na zlokalizowanych „wyspach”, a model + podstawowy projekt pozostaną niezmienione.</p> <p>w większości baz danych a <code>not null</code> kolumna będzie bardziej wydajna pod względem przechowywanych danych z podanego powodu, a także bardziej wydajna w wyszukiwaniu i indeksowaniu - więc jeśli nie chcesz zezwalać na wartości null w kolumnie, powinieneś je wyraźnie zabronić.</p><p>będzie to miało niewielki wpływ na wydajność, ponieważ dodatkowe <code>not null</code> ograniczenia będą potencjalnie musiały być sprawdzane dla każdego wiersza, którego dotyczy zmiana za pomocą insert lub update, ale ponieważ większość baz danych jest względnie łatwa do zapisu i bardzo obciążona odczytem, ​​prawdopodobnie nie stanowi to problemu (mało czasu poświęconego na to jest zauważalne przy w każdym razie, ponieważ jest to operacja związana z procesorem, w której reszta operacji wstawiania/aktualizacji będzie związana z operacjami we/wy, a więc o wiele bardziej znaczącym „wąskim gardłem” i daje pewne „bezpłatne” sprawdzanie danych, więc kod (lub inny) kod osoby) nie może przypadkowo umieścić wartości null tam, gdzie inny kod ich nie oczekuje, a zatem może dawać nieprawidłowe wyniki w ich obecności.</p><p>edycja: jak peter wskazuje w swoim komentarzu, powyższe jest generalizmem i może nie być prawdziwe dla <em>wszystkich</em> dmbs, chociaż jestem prawie pewien, że tak jest w przypadku mysql i mssql. inne komplikacje w tym obszarze mogą obejmować takie funkcje, jak rzadkie tabele (na przykład zaimplementowane mssql 2008), które zmienią dynamikę wydajności (nie) zerowalnych kolumn.</p> <p>jak już powiedziano, nie ma sposobu.</p><p>jedną z rzeczy, które robimy, jest szybkie sprawdzenie w nagłówku skryptu, aby ustalić, czy tryb sqlcmd jest włączony (i zakończyć skrypt, jeśli nie jest):</p><pre><code>:setvar databasename "mydatabase" go if ('$(databasename)' = '$' + '(databasename)') raiserror ('this script must be run in sqlcmd mode. disconnecting.', 20, 1) with log go -- the below is only run if sqlcmd is on, or the user lacks permission to raise fatal errors if @@error != 0 set noexec on go print 'you will not see this unless sqlcmd mode is on' -- rest of script goes here go set noexec off go </code></pre><p>jest powód, dla którego używany jest wskaźnik ważności 20, który ma tendencję do natychmiastowego przerywania połączenia, uniemożliwiając uruchomienie dodatkowego kodu skryptu, nawet jeśli w skrypcie znajdują się <code>go</code> terminatory wsadowe.</p><blockquote> <p> <a href="https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-error-severities">istotność 20–24</a> :</p> <p>wskazują problemy systemowe i są to błędy krytyczne, co oznacza, że ​​zadanie aparatu bazy danych, które wykonuje instrukcję lub partia, nie jest już uruchomione. zadanie rejestruje informacje o tym, co się wydarzyło, a następnie zostaje zakończone. w większości przypadków <strong> połączenie aplikacji z instancją aparatu bazy danych może również zostać zakończone </strong>. jeśli tak się stanie, w zależności od problemu aplikacja może nie być w stanie połączyć się ponownie.</p> <p>komunikaty o błędach w tym zakresie mogą wpływać na wszystkie procesy uzyskujące dostęp do danych w tej samej bazie danych i mogą wskazywać na uszkodzenie bazy danych lub obiektu. komunikaty błędów o poziomie ważności od 19 do 24 są zapisywane w dzienniku błędów.</p> </blockquote> <p>nigdy nie odłączaj podejrzanej bazy danych. w każdym razie, jak załączyłeś bazę danych po jej odłączeniu? użyłeś <code>create database</code> z opcją <code>for attach\_rebuild\_log</code>?</p><p>te polecenia powinny załatwić sprawę:</p><pre><code>alter database recovery\_test\_2 set emergency; alter database recovery\_test\_2 set single\_user; dbcc checkdb (recovery\_test\_2, repair\_allow\_data\_loss) with no\_infomsgs, all\_errormsgs; </code></pre><p>napisałem post dotyczący tej sytuacji:</p><p> <a href="http://yrushka.com/index.php/database-recovery/sql-20052008-log-file-deleted-part-3-2/">sql 2005/2008 procedura odzyskiwania bazy danych - usunięto plik dziennika (część 3)</a> </p><p>pytałeś o różnicę między:</p><ul> <li><code>dbcc checkdb ('&lt;dbname&gt;', repair\_allow\_data\_loss)</code> i</li> <li><code>alter database &lt;dbname&gt; rebuild log on (name=&lt;dbname&gt;,filename='&lt;logfilepath&gt;')</code></li> </ul><p>chodzi o to, że możesz uruchomić oba pliki, aby odbudować plik dziennika, ale używając <code>checkdb</code> odbudujesz dziennik i sprawdzisz bazę danych pod kątem błędów integralności.</p><p>druga (zmiana bazy danych) nie będzie działać, jeśli po utracie pliku dziennika wystąpiły aktywne transakcje (niepisane na dysk). podczas uruchamiania lub dołączania sql server będzie chciał wykonać odzyskiwanie (wycofanie i przywrócenie) z pliku dziennika, którego nie ma. zdarza się to, gdy dysk ulega awarii lub następuje nieoczekiwane zamknięcie serwera, a baza danych nie zostaje całkowicie zamknięta. wydaje mi się, że to nie była twoja sprawa i wszystko dobrze dla ciebie rozwiązało.</p><ol> <li> <p><code>dbcc checkdb (dbname, repair\_allow\_data\_loss)</code> uruchom na bazie danych w stanie awaryjnym sprawdza bazę danych pod kątem błędów niespójności, próbuje najpierw użyć pliku dziennika do odzyskania od wszelkich niespójności. jeśli go brakuje, dziennik transakcji jest odbudowywany.</p> </li> <li> <p><code>alter database rebuild log on...</code> to procedura nieudokumentowana i wymaga kolejnego <code>dbcc checkdb</code>, aby naprawić wszelkie błędy.</p> </li> </ol> <p>przekazanie <a href="https://dba.stackexchange.com/questions/5774/why-is-ssms-inserting-new-rows-at-the-top-of-a-table-not-the-bottom/5775#5775">moja odpowiedź</a> na podobne pytanie dotyczące programu sql server:</p><blockquote> <p>w świecie sql porządek nie jest nieodłączną właściwością zestawu danych. w ten sposób nie otrzymujesz żadnych gwarancji z rdbms, że twoje dane wrócą w określonej kolejności - lub nawet w spójnej kolejności - chyba że zapytasz o swoje dane klauzulą ​​order by.</p> </blockquote><p>tak więc, aby odpowiedzieć na twoje pytanie:</p><ul> <li>mysql sortuje rekordy, jak chce, bez żadnej gwarancji spójności.</li> <li>jeśli zamierzasz cokolwiek polegać na tym zamówieniu, <strong> musisz określić żądane zamówienie za pomocą <code>order by</code>. robienie czegokolwiek innego to przygotowywanie się na niepożądane niespodzianki. </strong></li> </ul><p>jest to właściwość całego sql, nie tylko mysql. odpowiedni tekst w <a href="http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt">specyfikacja sql-92</a> to:</p><blockquote> <p>jeśli nie podano &lt;kolejność według klauzuli&gt;, kolejność wierszy q zależy od implementacji.</p> </blockquote><p>w specyfikacji kursorów znajdują się podobne fragmenty tekstu.</p> <p>w ssms musisz zmienić niektóre opcje:</p><p>narzędzia - opcje - wyniki zapytania - serwer sql - wyniki do siatki (lub tekstu) -&gt; <strong>względnij nagłówki kolumn podczas kopiowania lub zapisywania wyników</strong>.</p><p>zmienione ustawienia są stosowane do nowych, ale nie istniejących okien zapytań.</p>