SQL: ALTER DATABASE ALLOW_SNAPSHOT_ISOLATION waiting on ENABLE_VERSIONING

2019-08-14

Aplikacja nie chciała się uruchomić zgłaszając (i za to brawa dla programisty), że opcja ALLOW SNAPSHOT ISOLATION musi być włączona.

Niby prosta rzecz

ALTER DATABASE ... SET ALLOW_SNAPSHOT_ISOLATION ON

I co? Czekam i czekam… sprawdzam, co blokuje sesję. Wait time to ENABLE_VERSIONING. No dobrze – jeśli to pierwsza baza z tym ustawieniem, to może rzeczywiście coś tam się musi w tempdb przebudować? Ale komenda nie chce się skończyć!

Jak można przeczytać w https://www.sqlskills.com/help/waits/enable_versioning/

“Occurs when SQL Server waits for all update transactions in this database to finish before declaring the database ready to transition to snapshot isolation allowed state. This state is used when SQL Server enables snapshot isolation by using the ALTER DATABASE statement.

No dobrze, ale w mojej bazie nie ma już żadnych połączeń. Co może być nie tak? Nawet checkpoint wyzwoliłem ręcznie, ale nic…. Czytaj dalej »

By Rafał Kraik in SQL

Python: if w postaci jednej linijki nie działa z pass

2019-08-09

W Pythonie wyrażenie if można zapisać w postaci jednolinijkowca:

expr1 if cond else expr2

Jednak łatwo wpaść w pułapkę. Takie wyrażenie zadziała:

print(price-bonus) if bonus_granted else print(price)

ale już takie nie:

print(price-bonus) if bonus_granted else price = 200
print(price-bonus) if bonus_granted  else pass

Ale po kolei:

price = 10

bonus = 1

bonus_granted = True

A teraz odpowiadając na pytanie. Przypomnijmy, że Pythonie można mieć statement i expressions:

  • statement – coś robi i niekoniecznie cokolwiek zwraca. Przykładem statement jest pass i przypisanie wartości do zmiennych
  • expression – to jest jedna lub więcej instrukcji, które coś zwracają. Przykładem expression jest np dowolny napis, dowolne obliczenie, ale też np. polecenie print (!!!!!!)

Jak sprawdzić czy coś jest expression? Prosto. Do zmiennej przypisz wynik wykonania polecenia, np.: Czytaj dalej »

By Rafał Kraik in Python

SQL: co sie dzieje, kiedy zmieniasz PageVerify na CHECKSUM?

2019-08-09

Stare bazy migrowane ze starych systemow SQL moga miec ustawiona opcje PageVerify na TORN_DETECTION. Oczywiscie to metoda z zeszlego wieku i aktualnie powinnismy uzywac CHECKSUM. Obie wartosci mowia o tym w jaki sposob kontrolowac, czy zapis strony bazy danych na dysk wykonal sie w 100%, czy tez sa jakies problemy. TORN_PAGE pozwoli dowiedziec sie tylko o tym czy zapis zostal zakonczony poprawnie, podczas gdy CHECKSUM pozwala sprawdzic czy podczas zapisu (lub odczytu) nie doszlo do przeklamania.

Zalozmy ze jedna z baz przetrwala od roku 2005 do dzisiaj z opcja TORN_PAGE. Co sie stanie kiedy zmienimy opcje na CHECKSUM? Czy ta jedna zmiana spowoduje, ze serwer przeczyta wszystkie strony z dysku, wyliczy na nich sume kontrolna i zapisze dane spowrotem na dysk? Czy jezeli jakas strona byla uszkodzona i miala ustawiony bit odpowiadajacy za TORN_DETECTION to czy ten blad bedzie nadal widoczny? Czytaj dalej »

By Rafał Kraik in SQL

SQL: Uprawnienie db_owner bez usuwania bazy danych

2019-08-09

Sam nie wiem z czego to wynika, ale uzytkownicy proponuja czasami nieco abstrakcyjne rozwiazania zwiazane z ustawieniem uprawnien do bazy danych.

W tym przypadku klient chcial aby uzytkownicy bazy danych mogli pracowac na poziomie uprawnien db_owner, ale z jednym malym haczykiem. Uzytkownicy nie powinni moc usunac bazy danych. Dlaczego uwazam, ze zyczenie jest nieco abstrakcyjne? Otoz db_owner to bardzo wysokie uprawnienie, wiec zlosliwy uzytkownik moze:

  • pousuwac tabele
  • zmodyfikowac procedury
  • zabrac uprawnienia innym uzytkownikom
  • itp.

Wydaje sie ze lepszym rozwiazaniem byloby wybranie tylko tych uprawnien, ktore sa rzeczywiscie potrzebne i nadanie ich do roli bazy danych. Potem uzytkownikow wystarczy przypisywac do tej roli. Byloby bezpieczniej.

No ale… usuniecie bazy danych jak opisano w https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-database-transact-sql?view=sql-server-2017 moze byc wykonane tylko w 3 przypadkach:

  • uzytkownik ma upranienie ALTER ANY DATABASE
  • uzytkownik ma uprawnienie CONTROL
  • uzytkownik jest db_ownerem

Requires the CONTROL permission on the database, or ALTER ANY DATABASE permission, or membership in the db_owner fixed database role.

Skoro u nas uzytkownik jest db_ownerem, to mozna mu zabrac uprawnienie do kasowania bazy tylko na 2 sposoby:

  • deny alter any database to user_name
  • deny control on database::db_name to user_name

Czytaj dalej »

By Rafał Kraik in SQL

Windows: Cluster: Ukryty zasob sieciowy C:\ClusterStorage

2019-08-09

Podczas instalacji Windows Failover Cluster na nodach clustra tworzony jest udostpniony zasob wskazujacy na C:\ClusterStorage

Takie „ukryte” zasoby sa czesto wychwytywane przez osoby pilnujace bezpieczenstwa serwerow, tymczasem ten powinien byc od razu wciagniety na white-list. Katalog ten pozwala w clustrze sledzic wykorzystanie Cluster Shared Volume (CSV), co jest dokladniej opisane na stronie Microsoft:

https://docs.microsoft.com/en-us/windows-server/failover-clustering/failover-cluster-csvs

R #07 – eksport wykresu do pliku – tutorial

2019-07-14

To dobrze móc wygenerować wykres w środowisku programistycznym, ale jeśli te wykresy mają np. dalej podlegać publikowaniu w intranecie i chciałoby sie aby te wykresy były zawsze aktualne, wtedy przyda się eksportowanie danych do pliku. Skrypt będzie można uruchamiać batchowo, bez udziału człowieka, a jednym z zadań skryptu będzie aktualizacja pliku.

W  pierwszym kroku należy otworzyć nowe urządzenie. Tym urządzeniem będzie teraz plik PNG o zdefiniowanej wysokości, szerokości i rozdzielczości. Po otwarciu urządzenia, rysowanie wykresu będzie się odbywać właśnie tam. Wobec tego uruchomienie polecenia plot, nie spowoduje narysowania czegokolwiek na ekranie. Wszystko będzie odbywać się w pliku graficznym. Ostatnim poleceniem jest zamknięcie urządzenia za pomocą dev.off():

png('c:/temp/chicken_chart.png', width = 500, height = 350, res = 72)

plot(x=1:nrow(chickwts), y=chickwts$weight,
 col=color_column, pch = shapes_column,
 xlab = 'Chicken', ylab = "Chicken's weight")

legend("topleft", legend = levels(chickwts$feed),
 col = my_colors,
 pch = my_shapes )

dev.off()

 

By Rafał Kraik in R

R #06 – kompozycja wykresów – tutorial

2019-07-14

Zależnie od sytuacji, czasami chcemy mieć duży i dokładny wykres, co pozwala dokłądnie przyjrzeć się poszczególnym elementom wykresu. Innym razem zadowolisz się po prostu ogólną znajomością sytuacji i wtedy przyda się kilka wykresów na raz prezentujących różne zależności, chociaż zdecydowanie mniejszych i mniej dokładnych.

W języku R za układ wykresu odpowiada kilka parametrów sesji. Możesz je wyświetlić korzystając z polecenia:

par()

Aby przekonfigurować środowisko tak, aby na raz pojawiały się 3 wykresy ułożone poziomo jeden nad drugim wykonaj polecenie:

par(mfrow=c(3,1))

Teraz pozostaje rysować wykresy:

barplot(feed_mean,
 main="Average chicken weight depending on feed",
 ylab="weight",
 xlab="feed type")

hist(ord_chick$weight, breaks = 10, ylim=c(0,10),
 ylab="Number of chickens", xlab="Chicken's weight")

barplot(data = chickwts,height = chickwts$weight,
 col=color_column, pch = shapes_column)

Czytaj dalej »

By Rafał Kraik in R