Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird der Fehler 701 erläutert, der auftreten kann, wenn Sie einen großen Batch von Vorgängen in SQL Server ausführen. Weitere Ursachen von 701-Fehlern finden Sie unter MSSQLSERVER_701.
Ursprüngliche Produktversion: SQL Server
Ursprüngliche KB-Nummer: 2001221
Problembeschreibung
Wenn Sie in SQL Server einen großen Batch von Remoteprozeduraufrufen (RPC) ausführen (z. B. Zehntausende von Einfügungen in einem einzelnen Batch), schlägt der Vorgang möglicherweise mit den folgenden Fehlern fehl, die im SQL Server-Fehlerprotokoll gemeldet werden:
2020-07-04 13:30:45.78 spid56 Error: 701, Severity: 17, State: 193.
2020-07-04 13:30:45.78 spid56 There is insufficient system memory to run this query.
Wenn Sie die Ausgabe von DBCC MEMORYSTATUS überprüfen, die automatisch bei 701 Fehlermeldungen beim Fehlerprotokoll protokolliert wird, finden Sie Einträge wie die folgenden:
2020-07-04 13:30:45.74 spid56 Failed allocate pages: FAIL_PAGE_ALLOCATION 1
2020-07-04 13:30:45.76 spid58
Memory Manager
VM Reserved = 1657936 KB
VM Committed = 66072 KB
AWE Allocated = 2351104 KB ==> ~2.2 GB
Reserved Memory = 1024 KB
Reserved Memory In Use = 0 KB
2020-07-04 13:30:45.76 spid56
USERSTORE_SXC (Total)
VM Reserved = 0 KB
VM Committed = 0 KB
AWE Allocated = 0 KB
SM Reserved = 0 KB
SM Committed = 0 KB
SinglePage Allocator = 1127848 KB==> ~1.07 GB
MultiPage Allocator = 0 KB
2020-07-04 13:30:45.78 spid56 Error: 701, Severity: 17, State: 193.
2020-07-04 13:30:45.78 spid56 There is insufficient system memory to run this query.
Notiz
Beachten Sie die großen Zuordnungen für den Cache USERSTORE_SXC
.
Wenn Sie außerdem die sys.dm_os_memory_clerks dynamische Verwaltungsansicht (DYNAMIC Management View, DMV) abfragen, während der Batch ausgeführt wird, zeigt die single_pages_kb
Spalte für den USERSTORE_SXC
Cache ein kontinuierliches Wachstum über einen Zeitraum an, der den Fehler 701 generiert.
Ein Beispiel für eine Anwendung, die dieses Verhalten möglicherweise aufweisen könnte, finden Sie unter "Weitere Informationen".
Ursache
Die Zum Speichern einer Anforderung in SQL Server zugewiesene Speichermenge hängt von folgenden Faktoren ab:
- Die Batchgröße (Anzahl der RPCs pro Anforderung).
- Die Anzahl der Parameter.
- Der Typ der Parameter.
Bei bestimmten Parametertypen (z . B. sql_variant) kann SQL Server die Anforderungen im Arbeitsspeicher potenziell ineffizient speichern. Wenn ein Client eine große Anzahl von Anforderungen sendet, die diese Parametertypen verwenden, können mehrere RPCs in einer Anforderung gesendet werden. In diesem Szenario sammelt der Server die gesamte Anforderung im Arbeitsspeicher, bevor sie ausgeführt wird. Dies könnte möglicherweise zu dem 701-Fehler führen, der in Den Symptomen behandelt wird.
Das Problem ist in älteren Versionen von SQL Server weit verbreiteter (insbesondere bei Verwendung des sql_variant
Datentyps). SQL Server 2008 und höhere Versionen verfügen über einige Entwurfsverbesserungen, die die Menge des verwendeten Arbeitsspeichers in bestimmten Fällen reduzieren und insgesamt effizienter sind.
Lösung
Verwenden Sie zum Beheben des Fehlers eine der folgenden Methoden:
- Reduzieren Sie die Batchgrößen.
- Parametertypen ändern. Ersetzen Sie
sql_variant
z. B. durch andere Typen.
Der USERSTORE_SXC
Cache wird für Zuordnungen auf Verbindungsverwaltungsebene verwendet, z. B. RPC-Parameter und den Arbeitsspeicher, der mit vorbereiteten Handles verknüpft ist. Wenn ein Client eine Anforderung sendet, die einen großen Batch an RPC-Aufrufen enthält, kann jeder eine große Anzahl bestimmter Parametertypen verwenden, z sql_variant
. B. zu übermäßigen Zuordnungen aus diesem Cache, wodurch der gesamte verfügbare Speicher erschöpft wird.
Die Anwendung sollte auch überwacht werden, um sicherzustellen, dass Sie vorbereitete Handles zeitnah schließen. Wenn Sie diese Handles nicht schließen, wird verhindert, dass SQL Server Arbeitsspeicher für die zugehörigen Objekte auf serverseitiger Seite freigibt.
Weitere Informationen
Um das in diesem Artikel beschriebene Problem zu reproduzieren, erstellen Sie eine Anwendung mithilfe des folgenden Codes, und beachten Sie, dass der USERSTORE_SXC
Cache wächst und verkleinern wird, während das Programm ausgeführt wird.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace RPCBatching
{
class Program
{
static void Main(string[] args)
{
DataTable t = new DataTable();
t.Columns.Add("a", typeof(int));
for(int i=0;i<100000;i++)
t.Rows.Add(1);
// pre-create the table with "CREATE TABLE t (a sql_Variant)" in a database named as test
using (SqlConnection conn = new SqlConnection("server=tcp:localhost; integrated security=true; database=test"))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(null, conn);
da.InsertCommand = new SqlCommand("INSERT INTO t VALUES (@a)", conn);
da.InsertCommand.Parameters.Add("@a", SqlDbType.Variant, 0, "a");
da.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
da.UpdateBatchSize = 100000;
da.InsertCommand.CommandTimeout = 12000;
da.Update(t);
}
}
}
}