AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 298178
Accepted
Thomas
Thomas
Asked: 2021-08-18 15:12:54 +0800 CST2021-08-18 15:12:54 +0800 CST 2021-08-18 15:12:54 +0800 CST

Estratégias quando DBCC CheckDB REPAIR_ALLOW_DATA_LOSS não pode reparar um banco de dados

  • 772

Para tirar isso do caminho, neste cenário, estamos reparando um banco de dados numérico onde nenhum backup foi feito antes da corrupção, portanto, restaurar um backup não é uma opção. Não é meu banco de dados :)

Ao executar o DBCC CHECKDB com REPAIR_ALLOW_DATA_LOSS, obtemos milhares de erros parecidos com este:

Msg 8928, Level 16, State 1, Line 7
Object ID 2105058535, index ID 1, partition ID 72057594038779904, alloc unit ID 72057594039762944 (type LOB data): Page (1:24911) could not be processed.  See other errors for details.
        Repairing this error requires other errors to be corrected first.
Msg 8965, Level 16, State 1, Line 7
Table error: Object ID 2105058535, index ID 1, partition ID 72057594038779904, alloc unit ID 72057594039762944 (type LOB data). The off-row data node at page (1:24911), slot 0, text ID 265289728 is referenced by page (1:24820), slot 0, but was not seen in the scan.
        Repairing this error requires other errors to be corrected first.
Msg 8928, Level 16, State 1, Line 7
Object ID 2105058535, index ID 1, partition ID 72057594038779904, alloc unit ID 72057594039762944 (type LOB data): Page (1:24912) could not be processed.  See other errors for details.
        Repairing this error requires other errors to be corrected first.
Msg 8965, Level 16, State 1, Line 7
Table error: Object ID 2105058535, index ID 1, partition ID 72057594038779904, alloc unit ID 72057594039762944 (type LOB data). The off-row data node at page (1:24912), slot 0, text ID 265289728 is referenced by page (1:24820), slot 0, but was not seen in the scan.
        Repairing this error requires other errors to be corrected first.
Msg 8928, Level 16, State 1, Line 7
Object ID 2105058535, index ID 1, partition ID 72057594038779904, alloc unit ID 72057594039762944 (type LOB data): Page (1:24913) could not be processed.  See other errors for details.
        Repairing this error requires other errors to be corrected first.

Executá-lo repetidamente não reduz os erros, portanto, parece que o DBCC não pode reparar isso.

Meu próximo pensamento foi tentar identificar e excluir as linhas problemáticas na tabela. Quando tentei excluir uma linha problemática conhecida, ela também errou, então meu pensamento atual é extrair linhas válidas conhecidas em uma nova tabela com o mesmo esquema da antiga, descartar a tabela antiga e renomear a nova para corresponder ao antigo.

O problema com isso é que o SQL Server, em vez de fornecer um erro detectável, simplesmente descarta a conexão sempre que uma linha com problema é encontrada, então não consigo encontrar uma maneira programática de identificar as linhas 'boas'.

Existe alguma maneira no T-SQL de forçá-lo a fornecer um bom erro capturável para que eu possa percorrer a tabela e extrair as linhas boas ou algum modo 'avançado' de DBCC CHECKDB que possa repará-lo que não é t óbvio em qualquer lugar na web?

sql-server dbcc-checkdb
  • 1 1 respostas
  • 268 Views

1 respostas

  • Voted
  1. Best Answer
    Thomas
    2021-08-18T21:39:13+08:002021-08-18T21:39:13+08:00

    Então, consegui obter uma correção para extrair os documentos de trabalho e, em seguida, eliminar a tabela de problemas graças à ajuda fornecida nos comentários.

    O SQL abaixo por conta própria precisaria ser constantemente reexecutado manualmente, mas descobri que, colocando-o dentro de OPENQUERY para um SQL Server vinculado a si mesmo dentro de um bloco Try-Catch, consegui repetir o SQL até que ele foi feito.

    Depois de concluído, basta renomear a tabela Documents_rep de volta para o nome original e descartar a tabela usada como uma correção rápida e suja para rastrear se a execução foi concluída.

    Eu também me deparei com o problema de OpenQuery emitindo uma transação implícita e rollback que eu resolvi através do COMMIT; declarações durante todo o script.

    USE [Database];
        IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'DocumentFixDone') BEGIN -- we dont want to start fixing a table that was already fixed
            IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'DOCUMENTS_rep') BEGIN 
                --create a table to hold the repaired documents
                CREATE TABLE [dbo].[DOCUMENTS_rep](
                    [RECORDID] [int] IDENTITY(1,1) NOT NULL,
                    [CONTENT] [image] NULL,
                    Status INT NOT NULL DEFAULT 0
                    -- 0 = not tried
                    -- 1 = In progress
                    -- 2 = Successful
                    -- 3 = Failed
                );
        
                --index the status field to make our searches faster
                CREATE INDEX    Documents_Status
                ON              Documents_rep
                                (Status);
    
                SET IDENTITY_INSERT Documents_rep on;
                --populate this with everything but the content from the broken table, default the status to 0
                INSERT INTO Documents_rep
                            ([RECORDID])
                SELECT  [RECORDID]
                FROM    DOCUMENTS
    
        
                SET IDENTITY_INSERT Documents_rep off;
            END
    
            --grab the in progress document from the last round and set it to failed
            UPDATE DOCUMENTS_rep 
            SET     Status = 3
            WHERE   Status = 1
    
            COMMIT; --need a commit because openquery starts a transaction
    
    
            DECLARE @currentRecordID int;
    
            --check if we have remaining rows and begin looping through and bringing them into the rep table
            WHILE EXISTS (SELECT 1 FROM Documents_rep WHERE Status IN (0)) BEGIN
                --get the lowest doc DB
                SET @currentRecordID = (SELECT min(REcordID) FROM Documents_rep WHERE Status = 0);
    
                --update it to in progress so if the script dies halfway through on restart it gets marked as invalid
                UPDATE  Documents_rep 
                SET     Status = 1 
                WHERE   RECORDID = @currentRecordID
    
                COMMIT; --need a commit because openquery starts a transaction
    
                --update the status to 2 and the content to be the equiv content from the docs table
                UPDATE  Documents_rep
                SET     Content = (SELECT d2.Content FROM Documents d2 WHERE d2.RECORDID = @currentRecordID), Status = 2
                WHERE   RecordID = @currentRecordID
    
                COMMIT; --need a commit because openquery starts a transaction
    
            END
    
            --track that weve completed the fix for documents
            CREATE TABLE DocumentFixDone (Recordid int);
    
            --once we are done, drop the old documents table, rename the existing one and move it across
            DROP TABLE Documents;
            DROP INDEX Documents_status ON DOCUMENTS_REP;
            ALTER TABLE Documents_rep 
            DROP COLUMN Status;
            ;
    
            COMMIT; --need a commit because openquery starts a transaction
        END
        ELSE
        BEGIN
            SELECT 'FixAlreadyComplete' AS FixStatus
        END
    
        
    
    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve