Mengembalikan memori dari SQL Server

10

Saya memiliki contoh SQL Server yang penggunaan memori secara bertahap tumbuh sampai windows tidak akan memberikannya lagi. Tampaknya logis bahwa hasil kueri besar sesekali akan menyebabkan instance tumbuh.

Apakah ada cara saya bisa meyakinkan SQL Server untuk melepaskan memori itu tidak perlu lagi (selain memulai ulang layanan)?

Sunting:
Saya menggunakan SQL Server 2000 SQL Server 8.00.2039 - SP4 (Edisi Standar)

Saya bisa mengetahuinya menggunakan permintaan berikut:

SELECT 'SQL Server ' 
    + CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - ' 
    + CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' (' 
    + CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'
BIBD
sumber

Jawaban:

19

Beginilah seharusnya SQL Server bekerja.

Jika Anda memiliki layanan lain di mesin itu dan tidak ingin SQL menggunakan semua memori yang tersedia, Anda perlu mengatur memori server maksimum. Lihat Opsi Memori SQL Server di MSDN.

Portman
sumber
1
Kedengarannya lebih seperti bug daripada fitur ... itu terjadi padaku. SQL Server mengambil 95% dari RAM yang tersedia untuk melakukan sesuatu, dan gagal untuk melepaskannya ketika sudah selesai.
Alkimia
1
@Alchemical Tergantung apa yang Anda maksud dengan " complete ". SQL Server dapat menggunakan semua RAM di komputer; menggunakannya sebagai cache disk. Itu tidak " lengkap " menggunakannya sebagai cache disk sampai Anda selesai menggunakan SQL Server.
Ian Boyd
8

Poster-poster lain benar bahwa ini adalah desain, tetapi Anda benar-benar ingin membatasi memori maks menjadi sedikit kurang dari RAM server Anda. Pikirkan tentang urutan kejadian ini:

  • SQL 2000 berjalan dengan gembira, menghabiskan semua RAM server Anda
  • Seseorang di RDP, atau Anda harus menarik IE untuk mengunduh tambalan, atau cadangan Anda dimulai, apa pun
  • SQL harus mengalokasikan dan membebaskan memori yang cukup agar OS berfungsi
  • Performa menyebalkan saat sedang membebaskan memori dan paging ke disk
  • Segalanya berjalan cukup baik begitu stabil
  • Operasi lainnya selesai dan SQL secara bertahap mendapatkan kembali RAM yang dibebaskan
  • Ulang

Untuk menghindarinya, konfigurasikan batas memori server maks Anda menjadi sekitar 80-90% dari memori fisik Anda yang sebenarnya. Petunjuk untuk SQL 2000 di: http://msdn.microsoft.com/en-us/library/ms178067.aspx

sh-beta
sumber
Ingat perilaku ini adalah 2005 dan 2008 - 2000 tidak melepaskan memori saat diminta ke OS.
Paul Randal
2
Tidak persis sesuai permintaan, tetapi itu melepaskan memori kembali ke OS. Dari tautan yang saya posting: "Ketika SQL Server menggunakan memori secara dinamis, ia menanyakan sistem secara berkala untuk menentukan jumlah memori fisik bebas. Di bawah Microsoft Windows 2000, SQL Server menumbuhkan atau mengecilkan cache buffer untuk menjaga memori fisik bebas antara 4 MB dan 10 MB tergantung pada aktivitas server. Mempertahankan memori bebas ini mencegah Windows 2000 dari paging. Jika ada lebih sedikit memori bebas, SQL Server melepaskan memori ke Windows 2000. Jika ada lebih banyak memori bebas, SQL Server mengalokasikan memori ke kumpulan buffer. "
sh-beta
Ah - benar - itu melakukan trik menonaktifkan sedikit memori fisik - Anda benar!
Paul Randal
4

Ini hanya akan melepaskannya jika OS menandakan bahwa itu adalah RAM yang kelaparan, atau jika Anda menghentikan dan memulai kembali layanan; yang harus dilakukan adalah membatasi jumlah maksimum SQL yang akan digunakan dengan mengkonfigurasi nilai 'max server memory'. Jika tidak ada hal lain di server yang membutuhkan RAM (dan mudah-mudahan tidak ada) saya tidak akan khawatir tentang hal itu.

SqlACID
sumber
4

Jadi, untuk merangkum jawabannya:

Tidak ada cara untuk meminta MS SQL Server untuk melepaskan memori yang tidak perlu segera. SQL Server harus secara otomatis melepaskan memori ketika diperlukan, tetapi tidak sebelum itu. Dan jika Anda mengalami masalah memori, Anda harus mengurangi nilai optin memori "maks server".

BIBD
sumber
3

SQL Server akan mengkonsumsi memori dan tidak mengembalikannya kecuali jika diberitahu oleh sistem operasi bahwa ada tekanan memori. Seperti yang ditunjukkan oleh Portman, ini sesuai desain, dan jika Anda ingin membatasi konsumsi memori, Anda perlu mengatur memori server maksimum yang akan digunakan oleh SQL Server.

K. Brian Kelley
sumber
2

Ingatlah bahwa perilaku yang Anda semua gambarkan adalah dari SQL Server 2005 dan seterusnya, ketika manajer memori ditulis ulang untuk (antara lain) menanggapi permintaan tekanan memori dari OS.

Untuk SQL Server 2000 dan sebelumnya, sekali ia mengambil memori, ia tidak akan mengembalikannya, tidak peduli berapa banyak teriakan OS untuk itu.

CodeSlave - apakah Anda menjalankan pada 2000, 2005, atau 2008?

Paul Randal
sumber
Ah ha ... ya memang SQL 2000.
BIBD
3
Itu tidak mengembalikan ketika OS berteriak untuk itu, tetapi TIDAK memberikannya kembali jika melihat bahwa OS di bawah ambang batas tertentu untuk memori fisik gratis. Lihat msdn.microsoft.com/en-us/library/ms178067.aspx
sh-beta
Dan untuk memperkuat apa yang dikatakan sh-beta, SQL Server 2000 hanya melepaskan memori ketika pemberitahuan bahwa OS rendah pada memori fisik karena tidak sampai Windows XP (2001) bahwa Windows menambahkan API untuk memungkinkan " OS berteriak untuk it "( msdn.microsoft.com/en-us/library/aa366799(v=vs.85).aspx ). SQL Server 2005 mengambil keuntungan dari fitur baru Windows itu. Tetapi ketika SQL Server 2000 ditulis tidak ada cara bagi OS untuk berteriak untuk itu, memaksa SQL Server untuk secara berkala memeriksa tekanan memori.
Ian Boyd
0

Pertanyaan lama, saya tahu, tetapi cara memaksa (lebih baru, setidaknya) SQL untuk melepaskan memori adalah dengan menulis aplikasi yang mengalokasikan sebanyak mungkin memori dalam potongan, menunggu (katakanlah) 15 detik (mis. Tidur (15000)) dan membebaskan memori yang dialokasikan dan keluar; Saya mencoba ini dan SQL tidak melepaskan memori sehingga sistem mendapatkan kembali RAM-nya; menulis kode seperti di atas hampir sepele menggunakan C / C ++, hanya masalah menyiapkan rantai stucts untuk menahan rantai blok memori (pointer dan ukuran), secara progresif mengurangi ukuran ketika "malloc ()" gagal hingga mencapai minimum (katakanlah kurang dari 1024) dan kemudian lintasi daftar tertaut untuk membebaskan kembali blok yang dialokasikan

A Passer by
sumber