Por que alguns DBMSs não permitem a reversão de determinadas instruções DDL?

21

Recentemente eu descobri que o MySQL não suporta reversão de DDL como "alter table" ... Estar acostumado ao PostgreSQL, isso me pareceu estranho, mas um amigo meu me disse que nem o Oracle o permite. Existem razões técnicas para não apoiá-lo? É simplesmente um recurso "desinteressante" para eles?

Edit: acabou de encontrar esta comparação . Parece que há muitas DBMSes que fazer DDL transacional apoio.

Joril
fonte
3
O MySQL não permite DDL dentro de uma transação. Antes de executar as instruções DDL, ele confirma a transação atual (todas as instruções DML atuais nessa transação!) Sem nenhum aviso.
precisa saber é o seguinte
Exatamente, muito chato IMO :)
Joril
Pessoalmente, estou surpreso que o Postgres permita - você pode reverter um DROPou um RENAME?
Joe
1
Contanto que você não elimine o banco de dados inteiro, sim :) Veja o link que acabei de adicionar
Joril
Portanto, apenas o Oracle e o MySQL não permitem instruções DDL nas transações. Esse recurso realmente permite implantações fáceis de esquema.
Marian

Respostas:

19

A razão pela qual isso funciona no PostgreSQL é que os catálogos do sistema são tabelas regulares. Portanto, a criação de uma nova função, por exemplo, requer apenas a inserção de uma linha na pg_proctabela, a alteração do valor padrão de uma coluna exige a atualização de alguma linha pg_attrdefe assim por diante. Como as tabelas são transacionais de qualquer maneira, você quase precisará se esforçar para não funcionar dessa maneira. (Muitos detalhes dolorosos da implementação foram omitidos aqui. ;-))

Suponho, sem conhecer o código fonte, que outros mecanismos de banco de dados usem algumas estruturas internas personalizadas para representar suas informações de catálogo do sistema. E, portanto, eles teriam que fazer um esforço extra, muito provavelmente, para fazer o DDL transacional funcionar, e aparentemente não é uma prioridade para eles.

O outro lado disso é que essa é a razão pela qual as principais atualizações de versão do PostgreSQL são tão dolorosas. Presumivelmente, outros produtos podem projetar suas estruturas internas de metadados com alterações e atualizações em mente, e, portanto, não há problemas com a atualização para uma nova versão principal. No PostgreSQL, não há como alterar uma tabela de catálogo do sistema para parecer repentinamente uma versão mais recente de uma tabela de catálogo do sistema, pelo menos não enquanto o sistema estiver online, pois isso exigiria acesso aos catálogos do sistema. Urgh.

Peter Eisentraut
fonte
1
Bem, eu preferiria meu banco de dados em um estado consistente o tempo todo, em vez da facilidade de atualização da versão do banco de dados, mas acho que é uma questão de opinião :) Obrigado pela explicação!
Joril
Isso pode explicar o problema de alguns bancos de dados, mas os catálogos do sistema são tabelas regulares no Oracle.
Leigh Riffel
10

A maioria não? Vadio.

Eu uso principalmente o SQL Server e ele faz. Eu sei que a Oracle não, mas achei que a Oracle poderia ser uma aberração.

No SQL Server, tenho certeza de que você pode executar várias instruções DDL em uma única transação, embora eu também pense que há algumas restrições (que eu esqueci). Você pode criar ou alterar ou soltar a maioria das coisas e revertê-la, se quiser. O Red-Gate SQL Compare (uma ferramenta que eu amo) tira proveito disso.

O problema é que o escopo da transação se torna bastante interessante ... Quando você envolve os catálogos do sistema em uma transação de atualização (DDL), corre o risco de realizar alguns bloqueios realmente importantes e pode bloquear o acesso aos catálogos do sistema. Os usuários não podem fazer muito se suas consultas não encontrarem suas tabelas nos catálogos!

No entanto, é útil poder incluir DDL em uma transação com várias instruções.

Mais útil, o comando DDL do SQL Server TRUNCATE também pode ser um elemento de uma transação com várias instruções . Você pode truncar uma tabela de destino (muito rápido), compilá-la e, em seguida, fazer uma confirmação se desejar o resultado. Se algo der errado, você reverte e pronto !, é como se você nunca tivesse perturbado a mesa. O espaço do log também é minimizado. Aproveito isso com bastante frequência.

KillerDBA
fonte
2
Aqui está uma resposta que mostra um exemplo de DDL vinculada à transação no SQL Server. Além disso, eu sempre pensei TRUNCATEque não poderia ser revertido. Eu estava errado.
21411 Nick Chammas
5

No SQL Server, podemos reverter as instruções DDL, não está usando a confirmação automática no final da instrução. Em outros DBMS eu não sei, mas lembro que no Oracle não se pode fazer o mesmo. Acredito que seja específico para cada DBMS, não tenho certeza do que o padrão SQL diria sobre isso, mas tenho certeza de que nenhum produtor implementa 100% do padrão.

Há uma pergunta semelhante no SO: é possível executar várias instruções DDL dentro de uma transação (no SQL Server)?

Marian
fonte
5

O Oracle compartilhou a análise de consultas, portanto, um SELECT * FROM table_a feito por uma sessão é (normalmente) o mesmo que o de outra sessão. Isso seria interrompido se uma sessão pensasse que havia dez colunas na tabela e outra pensasse que havia onze.

Gary
fonte
Interessante você deve dizer que, eu tive um problema semelhante no outro dia, o aplicativo deveria ser "quente" implementável, mas, ao alterar a estrutura da tabela para a nova versão, não havia como recompilar o JDBC PreparedStatements além de reiniciá-lo , tanto para esse!
Gaius
2
Como um aparte, a versão 11gR2 introduz o conceito de Edições para ajudar com atualizações quentes. Conexões efetivamente existentes usam uma edição (com cinco colunas). Você inicia uma nova edição, adiciona uma coluna e inicia algumas novas conexões usando a nova edição para novas sessões. Quando todas as sessões pendentes são concluídas, a edição antiga é inútil e tudo usa a nova edição. Sem reversão, mas você não coloca novas atividades em sua nova edição até que tudo funcione.
Gary