Page life expectancy spada do 0

Page life expectancy spada do 0
DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Witam

Jak w temacie mam problem z tym że Page life expectancy spada do 0, pomimo że

screenshot-20250313125551.png

a mam dostępne:

screenshot-20250313125618.png

Problem pojawił się po przeniesieniu plików tempdb na osobny dysk (któremu zmieniłem rozmiar alokacji 64KB jak zalecane jest), oraz ustawiłem:

screenshot-20250313125741.png

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Dodam że inny dysk na którym są pliki (.mdf) ma alokacje 4KB czy to może powodować problem ? Czy to że np. użytkownik SQL nie jest dodany Lock pages in memory ?

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 10 godzin
  • Postów:2367
0

Trudno powiedzieć, najlepiej zmierzyć co się dzieje:

  • waity
  • statystyki I/O
  • porównać do jakiegoś baseline'a (o ile taki masz)

Na logikę, skoro page life expectancy zmierza do 0, tzn. że jest duża presja na pamięć (bufory w pamięci są zapełnione i serwer robi miejsce na nowe strony)
To co mogło się wydarzyć:

  • zmiany planów zapytań (było po indeksach, a teraz jakieś zapytanie robi full table scan, albo był hash a teraz leci nested loop)
  • doszły nowe aplikacje ze słabymi zapytaniami
  • nadszedł ten czas w miesiącu, gdzie lecą jakieś raporty, przebudowy indeksów itp.

Szukałbym, która aplikacja generuje dużo I/O i zastanowił się dlaczego i czy to normalne dla tej aplikacji. Nie wiem czy przeniesienie tempa na inne dyski mogło być powodem zmiany planów zapytań.

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Dodam że tempdb były zmieniane z 5 na 8 na stała wartość

ALTER DATABASE tempdb MODIFY FILE (NAME = tempdev, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp2, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp3, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp4, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp5, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp6, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp7, SIZE = 10000MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb MODIFY FILE (NAME = temp8, SIZE = 10000MB, FILEGROWTH = 512MB);
GO

ALTER DATABASE tempdb MODIFY FILE (NAME = templog, SIZE = 5000MB, FILEGROWTH = 256MB);
GO

SELECT name, physical_name, size/128 AS size_MB FROM sys.master_files WHERE database_id = DB_ID(N'tempdb');
GO

screenshot-20250314095609.png

SELECT file_id, io_stall_read_ms, io_stall_write_ms
FROM sys.dm_io_virtual_file_stats(DB_ID('tempdb'), NULL);

screenshot-20250314095222.png

SELECT wait_type, waiting_tasks_count, wait_time_ms / 1000 AS wait_time_sec
FROM sys.dm_os_wait_stats
WHERE wait_type IN ('WRITELOG', 'PAGEIOLATCH_SH', 'PAGEIOLATCH_EX')
ORDER BY wait_time_sec DESC;

screenshot-20250314095255.png

A różnice alokacji

4KB -> dla dysku na którym są .mdf
64KB -> dla dysku na którym są tempdb

Nowe aplikacje nie doszły, raporty teraz też się nie mielą jakieś duże :(

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 10 godzin
  • Postów:2367
0

Czy ten nowy dysk, to jest dedykowany pod tempdb? Czy może jest współdzielony z innym workloadem? Jak jest podłączony do serwera? Co to za dysk (model)?
Jak wygląda użycie tego dysku od strony Performance Monitora? Przez jaki % czasy się nudzi? Jaka jest średnia długość kolejki requestów?

Wstaw coś więcej.

Kopiuj
SELECT log_pool_cache_size_mb, log_pool_cache_used_size_mb  FROM sys.dm_os_sys_info;
Kopiuj
SELECT
    instance_name AS DatabaseName,
    cntr_value AS LogFlushesPerSec
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Log Flushes/sec';
Kopiuj
SELECT * FROM sys.dm_io_virtual_file_stats(NULL, NULL);
Kopiuj
SELECT wait_type, waiting_tasks_count, wait_time_ms / 1000 AS wait_time_s
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE '%IO%'
ORDER BY wait_time_ms DESC;

Wg AWS allocation size nie ma zbyt dużego znaczenia -> https://aws.amazon.com/blogs/modernizing-with-aws/do-aws-customers-benefit-from-64kb-block-size-for-sql-server/

Dobrze byłoby sprawdzić, które transakcje mają największy wkład w tego WRITELOGa.

Kopiuj
SELECT 
    transaction_id, 
    database_id, 
    DB_NAME(database_id) AS database_name,
    database_transaction_begin_time, 
    database_transaction_log_bytes_used / 1024 AS log_kb_used,
    database_transaction_log_bytes_reserved / 1024 AS log_kb_reserved
FROM sys.dm_tran_database_transactions
ORDER BY log_kb_used DESC;

(do powyższego możesz dorzucić joina z sys.dm_exec_requests i pogrupować np. po userze i jeśli któryś user generuje ewidentnie dużo obciążenia, to przyjrzeć się bliżej sprawie).

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Nie jest dedykowany, aczkolwiek na ten moment są na nim jedynie tempdb'

Mam wersje

Microsoft SQL Server 2019 (RTM-CU30) (KB5049235) - 15.0.4415.2 (X64) Nov 18 2024 17:45:37 Copyright (C) 2019 Microsoft Corporation Standard Edition (64-bit) on Windows Server 2022 Standard 10.0 <X64> (Build 20348: ) (Hypervisor)

Natomiast:

SELECT
COUNT() AS Log_Pages,
COUNT(
) * 8 / 1024 AS Log_Buffer_MB
FROM sys.dm_os_buffer_descriptors
WHERE database_id = DB_ID() AND page_type = 'LOG';

screenshot-20250317080830.png

SELECT
instance_name AS DatabaseName,
cntr_value AS LogFlushesPerSec
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Log Flushes/sec'
order by LogFlushesPerSec desc;

screenshot-20250317080932.png

SELECT wait_type, waiting_tasks_count, wait_time_ms / 1000 AS wait_time_s
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE '%IO%'
ORDER BY wait_time_ms DESC;

screenshot-20250317081017.png

screenshot-20250317081141.png

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 10 godzin
  • Postów:2367
0

Wygląda, że masz bardzo dużo log flush na sekundę, czyli albo log buffer za mały, albo masz od groma maleńkich transakcji. Dużo log flushów -> presja na dysk -> presja na pamięć -> niskie page life expectancy.

Ile TPS ?

Kopiuj
SELECT 
    instance_name AS DatabaseName, 
    cntr_value AS TransactionsPerSecond
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Transactions/sec'
AND instance_name <> '_Total'
ORDER BY cntr_value DESC;

Jak to wygląda per baza.

Kopiuj
SELECT 
    instance_name AS DatabaseName, 
    cntr_value AS TransactionsPerSecond
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Transactions/sec'
AND instance_name <> '_Total'
ORDER BY cntr_value DESC;

Może ostatnio doszły jakieś nie cachowane sekwencje, które generuję te częste log flushe ?

Kopiuj
SELECT 
    r.session_id,
    r.status,
    r.command,
    r.cpu_time,
    r.reads,
    r.writes,
    r.logical_reads,
    est.text AS sql_text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) est
WHERE est.text LIKE '%NEXT VALUE FOR%'
ORDER BY r.writes DESC;

Która baza generuje najwięcej log flush?

Kopiuj
WITH LogFlushStats AS (
    SELECT 
        database_id,
        DB_NAME(database_id) AS DatabaseName,
        num_of_log_flushes,
        (num_of_log_flushes * 1.0) / NULLIF(io_stall_write_ms, 0) AS LogFlushesPerMs
    FROM sys.dm_io_virtual_file_stats(NULL, NULL)
    WHERE num_of_log_flushes > 0
)
SELECT 
    DatabaseName,
    num_of_log_flushes AS TotalLogFlushes,
    LogFlushesPerMs * 1000 AS LogFlushesPerSec
FROM LogFlushStats
ORDER BY LogFlushesPerSec DESC;

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

dla:

SELECT
instance_name AS DatabaseName,
cntr_value AS TransactionsPerSecond
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Transactions/sec'
AND instance_name <> '_Total'
ORDER BY cntr_value DESC;

screenshot-20250317132948.png

Ta pierwsza wartość to tempdb

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

zmieniłem

EXEC sp_configure 'recovery interval (min)', 5;
RECONFIGURE;

ale również nie zdało egzaminu

YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 10 godzin
  • Postów:2367
0

Pytanie, które sesje generują tyle TPSów na tempdb? I co on robią?

Kopiuj
SELECT 
    req.session_id,
    req.command,
    req.database_id,
    DB_NAME(req.database_id) AS DatabaseName,
    req.status,
    req.cpu_time,
    req.reads,
    req.writes,
    req.row_count,
    est.text AS sql_text
FROM sys.dm_exec_requests req
JOIN sys.dm_exec_sessions ses ON req.session_id = ses.session_id
CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) est
WHERE req.database_id = 2  -- tempdb 
ORDER BY req.writes DESC;
DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

jedynie:
screenshot-20250317144107.png
dla tempdb

edytowany 1x, ostatnio: DarekSQL
DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Ale moment jednak po zmianie:

EXEC sp_configure 'recovery interval (min)', 5;
RECONFIGURE;

Problem występował nadal, ale po wykonaniu:

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
GO

i zostawieniu

recovery interval (min)', 5

mam

screenshot-20250318080741.png
Jednak presja na presję na log flush chyba jest dalej dość spora

edytowany 1x, ostatnio: DarekSQL
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 10 godzin
  • Postów:2367
0

Skoro wcześniej zrobiłeś recovery interval -> 5 i nie pomogło, tzn. że częsty checkpoint prawdopodobnie nie był przyczyną. Jeśli pomogło FREEPROCCACHE, to możliwe, że był tam jakiś słaby plan wykonania, który powodował nadmierne I/O.

Co do loga, to pozostaje obserwować (np. co jakiś czas zapisywać wynik ostatniego zapytania, które podałem) i sprawdzić, które sesje generuję te zapisy. Możliwe, że któraś ma okres pobierania sekwencji, które nie są cachowane (lektura: https://sqlperformance.com/2018/11/sql-performance/understanding-log-buffer-flushes ) i problem za jakiś czas powróci.

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Racja i długo nie trzeba było czekać aby to nastąpiło :/ dodatkowo zauważyłem że ile nie przydzielę RAM to tyle SQL Serwer zje (przed zmianą plików temp) którye były jak niżej:

screenshot-20250319093213.png

DS
  • Rejestracja:10 dni
  • Ostatnio:około 20 godzin
  • Postów:10
0

Następną rzecz jaką zaobserwowałem to to że PLE spada do 0 po indeksacji indeksów, która wynika z maintance plan na poszczególnych bazach danych

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)