Problem beim Lesen von Daten von sekundären beim Reorganisieren des Clustered-Index

7

Wir haben eine AOAG in SQL Server 2014 SP2 CU5 (3 Knoten). Es gibt eine Datenbank mit Read Committed Snapshot Isolation Ebene ON . Wir haben einen großen Tisch komprimiert. Einige unserer größeren Abfragen in dieser Tabelle werden im Sekundärbereich ausgeführt.

Dann gibt es einen Nachtjob auf dem Primärknoten, um Indizes für mehrere Tabellen neu zu organisieren. Wenn es den Clustered-Index der genannten Tabelle erreicht, wird der folgende Fehler angezeigt:

Die Transaktion wurde abgebrochen, wenn auf die versionierte Zeile in der Tabelle 'xxxx' in der Datenbank 'yyyy' zugegriffen wurde. Die angeforderte versionierte Zeile wurde nicht gefunden, da der lesbare sekundäre Zugriff für den Vorgang, bei dem versucht wurde, die Version zu erstellen, nicht zulässig ist.

Irgendwann führten die großen Abfragen die Lesevorgänge mit dem Hinweis durch READUNCOMMITTED. Ich dachte, dass es die Ursache für diesen Fehler war, also entfernte ich sie. Aber der Fehler ist immer noch da.

Irgendwelche Ideen?

Aktuelles Setup:

  • 02 sekundär ist im synchronen Modus
  • 03 sekundär im asynchronen Modus

AOAG aktuelles Setup

Tabellendetails

  • RowCounts: 122.567.668
  • TotalSpaceMB: 18.460
  • UsedSpaceMB: 18.238

Definitionen:

CREATE TABLE [dbo].[big_table](
[ID] [int] NOT NULL IDENTITY(1, 1),
1 [int] NULL,
2 [datetime] NULL,
3 [int] NULL,
4 [int] NULL CONSTRAINT [DF_ccc_bUnits] DEFAULT ((0)),
5 [money] NULL,
6 [money] NULL,
7 [int] NULL,
8 [int] NULL CONSTRAINT [DF_ccc_MinDays] DEFAULT ((0)),
9 [int] NULL,
10 [int] NULL,
11 [float] NULL,
12 [money] NULL,
13 [int] NULL,
14 [int] NULL,
15 [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
16 [money] NULL,
17 [money] NULL,
18 [int] NULL,
19 [int] NULL,
20 [money] NULL,
21 [money] NULL,
22 [money] NULL,
23 [money] NULL,
24 [money] NULL,
25 [datetime] NOT NULL CONSTRAINT [DFcccadded] DEFAULT (getdate()),
26 [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
27 [money] NOT NULL CONSTRAINT [DFcccBrf] DEFAULT ((0)),
29 [money] NOT NULL CONSTRAINT [DFcccHB] DEFAULT ((0)),
30 [money] NOT NULL CONSTRAINT [DFcccFB] DEFAULT ((0)),
31 [money] NOT NULL CONSTRAINT [DFcccAllBoards] DEFAULT ((0)),
32 [money] NOT NULL CONSTRAINT [DFcccChildBrf] DEFAULT ((0)),
33 [money] NOT NULL CONSTRAINT [DFcccChildHB] DEFAULT ((0)),
34 [money] NOT NULL CONSTRAINT [DFcccChildFB] DEFAULT ((0)),
35 [money] NOT NULL CONSTRAINT [DFcccChildAllBoards] DEFAULT ((0)),
36 [int] NULL CONSTRAINT [DFcccShow_1] DEFAULT ((0)),
37 [timestamp] NOT NULL,
38 [money] NULL,
39 [money] NULL,
40 [money] NULL,
41 [money] NULL,
42 [money] NULL,
43 [money] NULL,
44 [money] NULL,
45 [money] NULL,
46 [int] NOT NULL CONSTRAINT [DFcccReleaseHour] DEFAULT ((0)),
47 [int] NULL,
48 [int] NULL,
49 [money] NULL,
50 [money] NULL,
51 [float] NULL
) ON [PRIMARY]
WITH (DATA_COMPRESSION = PAGE)
GO
CREATE UNIQUE CLUSTERED INDEX [IXccc] ON [dbo].[big_table] (1, 2) WITH (FILLFACTOR=90, DATA_COMPRESSION = PAGE) ON [PRIMARY]
GO
ALTER TABLE [dbo].[big_table] ADD CONSTRAINT [PKccc] PRIMARY KEY NONCLUSTERED ([ID]) WITH (DATA_COMPRESSION = PAGE) ON [secondary]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IXcccstamp] ON [dbo].[big_table] (36) INCLUDE (1, 2) WITH (FILLFACTOR=100) ON [PRIMARY]
GO
Jaroslaw
quelle
Haben Sie versucht, Ihren Nachtjob neu zu planen? Wie häufig tritt dieser Fehler auf? und wie oft müssen Sie Ihren Clustering-Schlüssel auf Ihrem großen Tisch neu ordnen? Es scheint, als hätte Ihre Tabelle entweder einen breiten Clustering-Schlüssel oder einen nicht ständig wachsenden Clustering-Schlüssel. Bei Ihren Abfragen zu sekundären Replikaten wird die Snapshot-Isolation (Zeilenversion) unter der Haube verwendet, selbst wenn Sie die Isolationsstufe explizit festlegen. Das Verwalten des Index in AG ist etwas schwierig. Versuchen Sie, Ihren Indexjob so zu verschieben, dass er nicht gleichzeitig mit Ihren Abfragen ausgeführt wird.
1
Die Verwendung der Zeilenversion wird erwartet. Auf diese Tabelle wird den ganzen Tag ohne Unterbrechung zugegriffen. Die beste Zeit ist nach Mitternacht, was wir bereits tun. Bereits verschoben, um andere schwere Jobs zu vermeiden, immer noch dieses Problem, nicht immer.
Jaroslaw
Folgendes würde ich empfehlen: Isolieren Sie den Clustered-Index von Ihrem Indexwartungsjob. Überprüfen Sie, ob Sie es vom Indexjob trennen können. Versuchen Sie, es außerhalb der Spitzenzeiten manuell auszuführen. Sehen Sie, wie es geht. Übrigens, wie lange dauert es, den Indexjob auszuführen? Warum müssen Sie den Index auch neu organisieren?
Haben Sie Glück beim Isolieren des Clustered-Index-Jobs? Es wäre hilfreich, auch die Indexjobdetails anzugeben (wie haben Sie die Indexpflege ausgeführt und wie lange hat es gedauert). Es scheint, dass dieses Problem ungewöhnlich ist und anderen zugute kommen würde, wenn Sie das Problem bereits gelöst haben.
Bisher hatten wir den Fehler noch ein paar Mal. Wir versuchen, den Job so weit wie möglich zu isolieren, damit wir gründliche Tests durchführen können. Führen Sie auch einige andere Tests durch, um unsere Indexwartungsjobs zu verbessern / zu aktualisieren und zusätzliche Arbeit zu vermeiden, die nicht wirklich erforderlich ist. Sobald ich Ergebnisse zu teilen habe, wird die Frage aktualisiert oder eine Antwort hinzugefügt.
Jaroslaw

Antworten:

0

Nachdem uns die möglichen Lösungen ausgegangen waren, haben wir Microsoft einen Support-Fall eröffnet. Sie baten darum, ein Tool auszuführen, um Informationen zu sammeln, während der Prozess ausgeführt wurde, und analysierten sie anschließend. Hier ist ihre Antwort:

  • Der ausgewählte Befehl wird ordnungsgemäß ausgeführt, wenn er gestartet wird, bevor der Reorganisationsindexjob initiiert wird
  • Der Befehl select schlägt fehl, wenn er nach dem Initiieren des Jobs zum erneuten Organisieren gestartet wird.
  • Gefunden das obige Verhalten ist erwartetes Verhalten in AG.
    • Obwohl die Lesevorgänge aufgrund der Zeilenversionierung keine gemeinsam genutzten Sperren erfordern, werden für diese Vorgänge Sch-S-Sperren (Schemastabilität) verwendet, mit denen Wiederherstellungsvorgänge blockiert werden können, bei denen DDL-Änderungen angewendet werden. DDL-Operationen umfassen ALTER / DROP-Tabellen und -Ansichten, jedoch nicht DROP oder ALTER von gespeicherten Prozeduren.
    • In unserem Fall, während der Neuorganisationsindex beim primären Wiederherstellungsvorgang ausgeführt wird, wird derselbe für das sekundäre Replikat ausgeführt und erhält Sch-M (Schemamodifikationssperren), wenn der Befehl select versucht, auf dasselbe Replikat zuzugreifen, auf das er nicht zugreifen kann Erwerben Sie Sch-S-Sperren (Schema Stability), da diese bereits von einem Redo-Thread mit Sch-M-Sperren belegt sind.
    • In diesem Szenario generiert Ihre Anwendung Fehler, einschließlich Timeout-Fehler.
  • Um solche Situationen zu vermeiden, wird empfohlen, eine Neuorganisation der Indexaufgabe außerhalb der Geschäftszeiten zu planen

Wir haben keine "außerhalb der Geschäftszeiten", wir laufen 24/7/365. Ist keine endgültige Antwort, aber zumindest kennen wir die Grundursache für dieses Problem. Der Ansatz besteht also darin, die Verbindungszeichenfolge vorübergehend zu ändern, damit die fehlgeschlagene Aufgabe am Tag der Neuindizierung vom primären AG-Knoten anstelle des sekundären AG-Knotens gelesen wird.

Jaroslaw
quelle