Acredito que entendo as razões por trás dos procedimentos armazenados protegidos e não protegidos.
Execução limitada "fora" do banco de dados (no nosso caso, DB2) para evitar possível corrupção do mecanismo do banco de dados, caso haja problemas com coisas como ponteiros.
Unfenced é executado "dentro" do banco de dados, o que significa que o desempenho é melhor.
Pelo que também pesquisei, o SQL PL sempre é basicamente não protegido, porque é SQL e, portanto, não pode acessar a memória como as linguagens de programação.
Os procedimentos C/C++ e Java podem ser executados com ou sem proteção. Mas, como eles podem acessar a memória, deve-se considerar executá-los protegidos, a menos que haja certeza da qualidade do código para não travar e que precise de desempenho.
Em primeiro lugar, estou correto em meu entendimento do que foi dito acima?
Em seguida, geralmente é uma prática recomendada começar com todos os procedimentos armazenados (mesmo aqueles definidos como SQL PL) como limitados primeiro?
Quaisquer outras práticas recomendadas para procedimentos armazenados, especialmente relacionados a cercas e/ou segurança?
EDIT: Pesquisas adicionais mostraram que os procedimentos SQL PL não podem ser executados com vedação. Como eles não contêm nenhum código que possa danificar o mecanismo do banco de dados, como ponteiros ou E/S de arquivo, o DB2 sabe que eles são seguros e os executa dentro do mecanismo (ou seja, sem proteção). Dito isto, ainda estou procurando as melhores práticas em relação a todos os outros procedimentos armazenados.
Para ser mais preciso, as
NOT FENCED
rotinas são executadas no mesmo espaço de processo que o próprio gerenciador de banco de dados. O mecanismo é escrito em C, portanto, chamar uma rotina não limitada é como chamar outra função C demain()
. É daí que vêm todos os aspectos de corrupção de memória e desempenho: uma rotina não limitada tem acesso a todos os mesmos recursos -- memória, arquivos, etc. -- como o próprio processo do gerenciador de banco de dados.Para uma
FENCED
rotina, o gerenciador de banco de dados inicia um processo separado (db2fmp
), que por sua vez executa o código da rotina. Como resultado, a proteção do sistema operacional impede que uma rotina limitada acesse qualquer área de memória ou recurso que pertença ao gerenciador de banco de dados.As rotinas SQL não podem ser protegidas , estritamente falando, porque elas não "executam", mas são ainda melhores do que não protegidas -- elas são bytecode que o próprio mecanismo de tempo de execução do DB2 executa, portanto, não há encadeamento ou processo separado.
As rotinas C e C++ podem ser protegidas, caso em que são executadas em processos separados, ou não protegidas, caso em que são carregadas no espaço do processo do gerenciador de banco de dados e chamadas como funções.
As rotinas Java só podem ser protegidas pelo fato de precisarem de um processo separado, a máquina virtual Java, para serem executadas. Se você declará-los como NÃO FENCED, a opção será silenciosamente ignorada.
Tendo dito tudo isso, sua única escolha entre cercado e não cercado é com rotinas C/C++. Normalmente, você executaria o modo protegido por segurança, mudando para o modo não limitado apenas quando tiver certeza de que eles não podem prejudicar o gerenciador de banco de dados e precisam de maior desempenho 1 .
1 - A diferença de desempenho entre rotinas protegidas e não protegidas vem da sobrecarga associada à alocação de um processo protegido, bem como das comunicações entre processos entre o gerenciador de banco de dados e a rotina não protegida. Mesmo assim, o processo protegido não é criado toda vez que uma rotina protegida é chamada; um conjunto deles será criado e reutilizado para tais chamadas. Tudo isso significa que você pode ver o benefício de declarar uma rotina como limitada apenas se essa rotina for chamada com muita frequência (como dezenas de vezes por segundo ou mais).
Tanto quanto eu posso dizer, você está quase certo. A chave é que as funções PL SQL não podem fazer alocação de memória e, portanto, não há como tratá-las especialmente em relação ao gerenciamento de memória. Em essência, o PL/SQL está intimamente ligado ao mecanismo de banco de dados, mas o gerenciamento de memória é responsabilidade do mecanismo de banco de dados, não dos procedimentos armazenados.
Em geral, minhas recomendações seriam para código extensivamente testado e/ou revisado com um histórico muito bom, destinado ao uso em sistemas de alto desempenho, não protegido faz mais sentido. No entanto, os bancos de dados são importantes e algo como uma saturação de buffer pode causar corrupção de dados que pode passar despercebida por algum tempo. Minha recomendação seria executar todos os procs armazenados em C/C++/Java protegidos, a menos que você tenha certeza de que precisa de outra forma.
O mesmo vale para UDFs.