Nie można kontynuować wykonywania, ponieważ sesja jest w stanie zabicia. podczas budowania indeksu klastrowego

11

Podczas próby utworzenia indeksu klastrowego pojawia się następujący błąd

Instrukcja została zakończona.
Wiadomość 596, poziom 21, stan 1, wiersz 0
Nie można kontynuować wykonywania, ponieważ sesja jest w stanie zabicia.

Msg 0, poziom 20, stan 0, wiersz 0
Wystąpił poważny błąd w bieżącym poleceniu. Ewentualne wyniki należy odrzucić.

Indeks to:

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT

BEGIN TRANSACTION
GO

CREATE CLUSTERED INDEX IX_CO_DES_INPUT 
ON dbo.CO_DES_INPUT(DESIGN_ID, PRODUCT_INPUT_NUM, INPUT_NAME)
          WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
               ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

ALTER TABLE dbo.CO_DES_INPUT 
  SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

Używam Microsoft SQL Server 2012 (SP3) (KB3072779) - 11.0.6020.0 (X64) Standard Edition (64-bit) w systemie Windows NT 6.3 (kompilacja 9600:)

Uciekłem

DBCC CheckDB ('concept-test') WITH NO_INFOMSGS, ALL_ERRORMSGS  

i nie znalazł żadnych problemów

Obawiam się, że moja baza danych jest uszkodzona, ponieważ otrzymuję ten błąd. Jak rozwiązać problem i umieścić ten indeks na stole?

użytkownik2904235
źródło
Otrzymuję ten sam błąd, gdy idę, aby dodać indeks nieklastrowany do tej samej tabeli. Najpierw próbowałem dodać nieklastrowany. Mam ten błąd. Pomyślałem więc, że mogę mieć uszkodzenie indeksu i próbowałem usunąć wszystkie indeksy i odtworzyć je. Właśnie wtedy otrzymałem komunikat o błędzie, który pierwotnie opublikowałem. Mogę dodać, że kontrola integralności SQL Idera wykryła uszkodzenie indeksów dla tej tabeli. Teraz pytanie brzmi, jak to naprawić.
user2904235
Czy to możliwe, że Twoja operacja zakończy się niepowodzeniem, gdy dowie się, że doszło do naruszenia ograniczeń lub coś takiego? Proszę spojrzeć na to: http://stackoverflow.com/questions/34518205/c-sharp-cmd-executescalar-cannot-continue-the-execution-becase-the-session
Victor Barajas

Odpowiedzi:

4

Tylko wskazówka dotycząca: SQL Server 2017 (gdzie napotykałem ten błąd) i niektóre wersje 2016, aby potencjalnie zaoszczędzić trochę czasu:

Przed SQL Server 2017 CU8 (także 2016 SP1 CU9 i 2016 SP2 CU1) występował problem polegający na tym, że tabele partycjonowane ze statystykami przyrostowymi generowały ten błąd, jeśli operacja DML spowodowała automatyczną aktualizację statystyk.

Minimalna strona KB jest tutaj:

https://support.microsoft.com/en-us/help/4163478/fix-access-violation-when-incremental-statistics-automatically-updated

Zainstalowanie późniejszej CU niż te wymienione powyżej rozwiązuje problem.

cbailiss
źródło
3

Może to być spowodowane korupcją indeksu,

Najlepszym sposobem na poradzenie sobie z tym jest upuszczenie starego indeksu, który jest uszkodzony.

DROP INDEX dbo.CO_DES_INPUT.IX_CO_DES_INPUT 

I niż Uruchom zapytanie w pytaniach, powinno działać dobrze, jeśli wszystkie rekordy są unikalne. w podanych kolumnach.

MarmiK
źródło
3

W bazie danych skonfigurowanej dla zawsze włączonych grup dostępności możesz również spotkać się z tym zachowaniem, jeśli grupa dostępności jest w trybie SYNCHRONICZNYM, a urządzenia pomocnicze przełączyły się w tryb offline lub zostały zawieszone. Jest to efekt uboczny, którego doświadczają serwery aplikacji. Dzięki,

Kangeles
źródło
2

Coś, co nieświadomie znalazłem: gdy wyłączasz / przebudowujesz indeksy w widoku indeksowanym, otrzymasz ten sam błąd, jeśli spróbujesz odbudować jedną lub więcej indeksów nieklastrowych przed zbudowaniem klastrowania lub użyj opcji ODBUDUJ WSZYSTKIE.

PseudoToad
źródło
2

Ten błąd zawsze pojawia się, gdy mam uruchomione zapytanie, używając programu nasłuchującego Always On AG, jednej z baz danych AG i następuje przełączenie awaryjne:

.Net SqlClient Data Provider: Msg 596, poziom 21, stan 1, wiersz 0 Nie można kontynuować wykonywania, ponieważ sesja jest w stanie zabicia. .Net SqlClient Data Provider: Msg 0, poziom 20, stan 0, wiersz 0 Wystąpił poważny błąd w bieżącym poleceniu. Ewentualne wyniki należy odrzucić.

Bardzo łatwe do odtworzenia! Oczywiście mogą być inne powody, ale jest to jeden konkretny przypadek, w którym pojawia się ten rodzaj błędu ...

HansLindgren
źródło
0

Mogę odtworzyć ten problem w dość małym programie w języku C #, który wykorzystuje połączenia asynchroniczne, ale nie jestem w 100% pewien, dlaczego. Oto mój program repro, na wypadek gdyby inni chcieli go wypróbować - podejrzewam, że istnieje szereg rzeczy, które muszą być idealnie dopasowane, aby tak się stało:

  • Pula połączeń włączona
  • Używanie personifikacji w puli połączeń, uniemożliwianie cofania tego kontekstu personifikacji w puli połączeń
void Main()
{
    var impersonateMyself = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

    var testCommand = "SELECT TOP 1 * FROM sys.objects";
    var calls = Enumerable.Repeat(
        $@"{testCommand};",
        10
    );
    var impersonatedCalls = Enumerable.Repeat(
        $@"EXECUTE AS LOGIN = '{impersonateMyself} WITH NO REVERT';  {testCommand}; REVERT;",
        10
    );
    Dictionary<string, object> dict = new Dictionary<string, object>()
    {
    };

    // Scenario 1: Impersonated Calls, With connection pooling -- will randomly fail
    Parallel.ForEach(
        impersonatedCalls,
        c => new SqlAsync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=2;").AsyncSqlCall<List<A>>(c, CommandType.Text, handleResultAsync, dict).Dump());

    Parallel.ForEach(
        impersonatedCalls,
        c => new SqlSync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=2;").SyncSqlCall<List<A>>(c, CommandType.Text, handleResultSync, dict).Dump());


    // Scenario 2: Normal calls, with connection pooling -- should succeed every time
    Parallel.ForEach(
        calls,
        c => new SqlAsync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=2;").AsyncSqlCall<List<A>>(c, CommandType.Text, handleResultAsync, dict).Dump());

    Parallel.ForEach(
        calls,
        c => new SqlSync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=2;").SyncSqlCall<List<A>>(c, CommandType.Text, handleResultSync, dict).Dump());



// Scenario 3: Impersonated Calls, WITHOUT connection pooling -- should succeed every time
    Parallel.ForEach(
        impersonatedCalls,
        c => new SqlAsync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=200;").AsyncSqlCall<List<A>>(c, CommandType.Text, handleResultAsync, dict).Dump());

    Parallel.ForEach(
        impersonatedCalls,
        c => new SqlSync("Data Source=devsql2;Initial Catalog=Test;Integrated Security=true;Max Pool Size=200;").SyncSqlCall<List<A>>(c, CommandType.Text, handleResultSync, dict).Dump());
}

public class SqlSync
{
    private readonly string _connectionString;
    public int Timeout {get; set;}

    public SqlSync(string connString)
    {
        _connectionString = connString;
        Timeout = 30;
    }

    public T SyncSqlCall<T>(string commandText, CommandType type, Func<SqlDataReader, T> handleResult, Dictionary<string, object> parameters = null)
    {
        using (SqlConnection conn = new SqlConnection(_connectionString))
        using (SqlCommand cmd = new SqlCommand(commandText, conn))
        {
            cmd.CommandTimeout = Timeout;
            cmd.CommandType = CommandType.Text;

            if (parameters != null)
            {
                foreach (KeyValuePair<string, object> kvp in parameters)
                    cmd.Parameters.AddWithValue(kvp.Key, kvp.Value ?? DBNull.Value);
            }

            conn.Open();

            using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                return handleResult(rdr);
        }
    }
}

public class SqlAsync
{
    private readonly string _connectionString;
    public int Timeout { get; set; }

    public SqlAsync(string connString)
    {
        _connectionString = connString;
        Timeout = 30;
    }

    public Task<T> AsyncSqlCall<T>(string sp, CommandType commandType, Func<SqlDataReader, Task<T>> handleResult, Dictionary<string, object> parameters = null)
    {
        return AsyncSqlCall<T>(sp, commandType, (reader, token) => handleResult(reader), CancellationToken.None, parameters);
    }

    public async Task<T> AsyncSqlCall<T>(string commandText, CommandType type, Func<SqlDataReader, CancellationToken, Task<T>> handleResult, CancellationToken cancellationToken, Dictionary<string, object> parameters = null)
    {
        using (SqlConnection conn = new SqlConnection(_connectionString))
        using (SqlCommand cmd = new SqlCommand(commandText, conn))
        {
            cmd.CommandTimeout = Timeout;
            cmd.CommandType = CommandType.Text;

            if (parameters != null)
            {
                foreach (KeyValuePair<string, object> kvp in parameters)
                    cmd.Parameters.AddWithValue(kvp.Key, kvp.Value ?? DBNull.Value);
            }

            await conn.OpenAsync(cancellationToken);

//          if (conn.State != ConnectionState.Open)
//              await Task.Delay(TimeSpan.FromMilliseconds(10));
            using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection, cancellationToken))
                return await handleResult(rdr, cancellationToken);
        }
    }
}

public class A
{
    public string object_name { get; set; }
}

public static Func<SqlDataReader, Task<List<A>>> handleResultAsync = (SqlDataReader sdr) =>
{
    var result = new List<A>();
    while (sdr.Read())
    {
        result.Add(new A { object_name = sdr.GetFieldValue<string>(0) });
    }
    return Task.FromResult(result);
};

public static Func<SqlDataReader, List<A>> handleResultSync = (SqlDataReader sdr) =>
{
    var result = new List<A>();
    while (sdr.Read())
    {
        result.Add(new A { object_name = sdr.GetFieldValue<string>(0) });
    }
    return result;
};
John Zabroski
źródło