Apa yang terjadi ketika tidak ada memori fisik yang tersedia untuk SQL Server?

16

Ketika mencari di Google, saya menemukan beberapa informasi yang saling bertentangan.

Beberapa situs menyatakan bahwa ketika tidak ada memori fisik yang tersisa untuk data, maka SQL Server memindahkan data yang sudah ada ke TEMPDB (lihat: SQL Server: Demystifying TempDb dan rekomendasi ).

Tetapi situs lain menyatakan bahwa, ketika tidak ada cukup memori fisik yang tersisa, sistem operasi dapat menggunakan PAGE FILE dan memindahkan data dari memori fisik ke sana (lihat Halaman File untuk SQL Server ).

Saya bertanya-tanya di mana SQL Server menulis data ketika kehabisan memori fisik? Untuk tempdb atau ke file Halaman OS? Atau mungkin keduanya?

RaufDBA
sumber

Jawaban:

28

ketika tidak ada memori fisik yang tersisa untuk data, maka SQL Server memindahkan data yang sudah ada ke TEMPDB

Artikel yang Anda tautkan paling menyesatkan, dan tidak benar di beberapa tempat. Saya pikir penulis sedang mencoba untuk terlalu menyederhanakan beberapa hal rumit, dan dalam melakukannya agak terlalu jauh.

SQL Server tidak memindahkan data dari memori (buffer pool) ke tempdb dengan cara itu. Ini menggunakan strategi caching "paling baru digunakan" (secara umum), jadi jika ada tekanan memori, dan data baru perlu ditarik ke dalam memori, SQL Server akan mengeluarkan data LRU dari buffer pool untuk mengakomodasi data baru. Perilaku ini sering dipantau oleh penghitung perfmon yang disebut "Page Life Expectancy" (PLE) :

Definisi PLE adalah waktu yang diharapkan, dalam hitungan detik, bahwa halaman file data membaca ke dalam buffer pool (cache di-memori dari halaman file data) akan tetap berada dalam memori sebelum didorong keluar dari memori untuk memberikan ruang bagi data yang berbeda. halaman file. Cara lain untuk memikirkan PLE adalah pengukuran instan dari tekanan pada buffer pool untuk membuat ruang kosong untuk halaman yang dibaca dari disk. Untuk kedua definisi ini, angka yang lebih tinggi lebih baik.

Selama eksekusi permintaan, SQL Server dapat menggunakan tempdb untuk operasi tertentu. Ini biasanya dilakukan jika perkiraan buruk, tetapi memori yang tersedia rendah dapat memengaruhi perilaku ini.

Beberapa operasi yang dapat "menumpahkan" ke tempdb dengan cara ini adalah hashing rows (untuk join atau agregat, dll), mengurutkan baris dalam memori, dan buffering rows selama eksekusi query paralel.

Kueri pengguna juga dapat secara eksplisit menggunakan tempdb (dengan tabel temporer global atau lokal), dan secara implisit menggunakan tempdb (dengan snapshot atau membaca level isolasi snapshot yang dilakukan).

Tak satu pun dari situasi ini yang benar-benar cocok dengan pernyataan yang Anda kutip.

ketika tidak ada cukup memori fisik yang tersisa, sistem operasi dapat menggunakan PAGE FILE dan memindahkan data dari memori fisik ke memori tersebut

Ini pasti dapat terjadi, dan berada di luar kendali SQL Server untuk sebagian besar. Ada tombol yang dapat Anda putar untuk mencegah beberapa jenis paging tingkat OS, yaitu menyalakan "Lock Pages in Memory" (LPIM) :

Kebijakan Windows ini menentukan akun mana yang dapat menggunakan proses untuk menyimpan data dalam memori fisik, mencegah sistem dari paging data ke memori virtual pada disk.

Jadi apa yang bisa kita cegah agar tidak dipetakan ke disk?

Sebelum SQL Server 2012, halaman yang dialokasikan melalui komponen yang disebut "Single Page Allocator" dikunci dalam memori (tidak dapat halaman). Ini termasuk kumpulan buffer (halaman database), cache prosedur, dan beberapa area memori lainnya.

Lihat Bersenang-senang dengan Halaman Terkunci, AWE, Manajer Tugas, dan Perangkat Kerja ... untuk detail, terutama bagian "4. Sekarang saya tahu bahwa SQL Server pada x64 dapat menggunakan" Halaman Terkunci ", apa sebenarnya yang dikunci?" Bacaan terkait tambahan dapat ditemukan di sini: Debat SQL Server Hebat: Halaman Kunci di Memori

Dalam SQL Server 2012 dan yang lebih baru, tidak ada "Alokasi Halaman Tunggal" (pengalokasi halaman tunggal dan multi-halaman digabung, per An In-depth in memory - SQL Server 2012/2014 ). Detail tentang apa, tepatnya, yang bisa dan tidak bisa dikelompokkan tidak didokumentasikan secara detail di mana pun yang pernah saya lihat. Anda dapat menggunakan kueri seperti ini untuk melihat apa yang dikunci:

select osn.node_id, osn.memory_node_id, osn.node_state_desc, omn.locked_page_allocations_kb
from sys.dm_os_memory_nodes omn
inner join sys.dm_os_nodes osn on (omn.memory_node_id = osn.memory_node_id)
where osn.node_state_desc <> 'ONLINE DAC'

Per artikel Dukungan MS yang sama, Anda juga dapat menggunakan DBCC MEMORYSTATUSuntuk melihat berapa banyak memori "terkunci."

Sebagai catatan, Anda dapat melihat bukti dari kumpulan kerja SQL Server yang dipetakan oleh OS di log kesalahan. Akan ada pesan yang terlihat seperti ini:

2019-09-02 10: 19: 27.29 spid11s Sebagian besar dari memori proses server sql telah dikumpulkan. Ini dapat menyebabkan penurunan kinerja. Durasi: 329 detik. Perangkat kerja (KB): 68780, berkomitmen (KB): 244052, pemanfaatan memori: 28%.

Josh Darnell
sumber
0

Versi modern SQL server memiliki peluang yang sangat kecil untuk menutup telepon sama sekali. SQL Server memuat .NET Framework ke dalam ruang alamatnya dan menggunakannya di bawah operasi normal. Jika memori fisik dan file halaman keduanya habis, Windows akan mencoba menumbuhkan file halaman; namun bahkan jika itu dapat menumbuhkan file halaman, ini bukan operasi instan, dan alokasi memori gagal saat file halaman tumbuh. Ada bug di .NET Asynchronous I / O handler di mana ia mengalokasikan memori sebagai respons terhadap pemberitahuan APC. Jika panggilan newgagal, itu akan melemparOutOfMemoryException. Pengecualian ini ditangkap dalam kode asli di dalam penjadwal tugas; namun I / O asinkron tampaknya tidak pernah selesai. Thread finalizer untuk FileStream akan memblokir menunggu I / O selesai sehingga dapat melepaskan pin buffer, sehingga menggantung thread finalizer selamanya. Ini menyebabkan .NET Framework untuk secara bertahap menggunakan lebih banyak dan lebih banyak memori sampai tidak ada lagi memori yang dapat dialokasikan, di mana titik SQL server akan menjadi tidak responsif karena winsock tidak dapat mengalokasikan buffer lagi sehingga bahkan koneksi akses admin tidak berguna.

Saya telah benar-benar menekan hangup total penjadwal tugas dalam aplikasi .NET karena kehabisan memori. Untungnya proses akhirnya mati karena melemparkan OutOfMemoryExceptionpada beberapa utas yang tidak menangkapnya setelah beberapa kegagalan sehingga kami bisa mengetahui apa yang sebenarnya menutup server.

Begitu saya tahu apa yang saya cari, menemukan bug dalam analisis statis itu mudah.

Joshua
sumber