Edition-Based Redefinition. Part 2

Hello! As promised in a previous post about Edition-Based Redefinition - here is the second part.







So what are we working with? Our main production server is Oracle 12C, Enterprise Edition. And, what is important to note, several dozen applications work on it simultaneously. Why are we focusing on this? The technology is relatively new, it is not very well run-in. And it would be illogical to transfer some critical systems to it right away. Therefore, we decided for ourselves that we will slowly move from less critical systems to more critical ones. Accordingly, the next problem we needed to understand: how to work with EBR technology and how to organize integration in the situation when we have one versioned version and the other not. In the 12th version of Oracle, as it turned out, you can create nonversioned objects, unversioned packages, unversioned representations in a versioned scheme for organizing the very integration.



Of course, we can create an unversioned API and give it to the nonversioned schema for use. But what if this non -version API (or part of it) is used inside our application and we need to version it inside ourselves, and give nonversioning objects to the side? This is just the next problem that we struggled with. We have used the API many times, but, as you remember, there is a limitation that versioned objects cannot be used nonversioned. Naturally, provided that several applications were running on the server, it was necessary to understand how we would switch one application to the new Edition and keep the ability to use the API of this scheme with other database schemes.



There are several options for installing Edition:





These options are dismissed immediately because at least some applications will not switch to using EBR.



It is also possible to create a service to determine the version, or to determine the version when connecting the application to the circuit. This is convenient if we connect to the database through some third-party application.



And if we need jobs to run on schedule and work in some specific edition? Accordingly, there is another option for switching to a new version - this is to orient the current session to a specific version .



Actually, we chose this for ourselves as a solution. You can hang a trigger on the versioned scheme after logon, which will say that the current session in this scheme will work in this edition.







Returning to the integration and duplication of logic. There are tasks: I want to version some kind of application logic inside my scheme, and I also need to expose it to a non -version user. At first it seemed that this could not be implemented, but after delving into the question, we looked that the regular dbms_sql package, which in principle is aimed at performing some kind of dynamic queries, can help in solving this problem. How? Very simple - when processing a request or calling any anonymous block, we can throw the condition name as a parameter, thereby indicating the version in which this code will be parsed and executed. If we need to use some procedure inside ourselves and give the same procedure to a third-party scheme, we simply wrap it with a call in the dbms_sql.parse procedure, thereby creating a wrapper that can be put in a non -version object, and - please, our versioned object can use nonversioned user.



What are you facing here? For some reason, when specifying condition, out parameters are not issued in the procedures. Why - it is not clear, but in those schemes in which we worked, this is not used often. Maybe weโ€™ll redo the logic somehow, or weโ€™ll look for some further solutions.







The following problems are bugs or features of the EBR that we encountered. The first is a problem with constructed types and pipelined functions. What does Pipeline have to do with it? Besides the fact that we have really certain algorithms that work on the basis of pipelined functions, Pipeline is a certain solution for putting the versioned view to the side. We inherited the views, which contain rather complicated logic for preliminary data processing, and third-party schemes also use these views. Accordingly, it was necessary to understand how to set our versioning views to a non -version data consumer circuit, provided that the output set of columns does not change. As some kind of solution, it was clear that you could wrap all these views with dbms_sql in the Pipeline function and ultimately put them in the view for the consumer, yes, this is resource-intensive for the server, but this would not require any modifications on the part of the receiving system.



So, returning to the use of pipelined functions, it turned out that if a type being constructed is not created in the existing version package, and it is being constructed for the first time, then the package simply does not compile and falls apart. Immediately a solution did not come, went to look for what was suggested by fellow programmers? Someone said that you need to create this type in the zero version of the package, or create a package with the corresponding type in the zero version of the database. It was not clear why to do this. They found a solution that these types, which are implicitly created when the package was compiled, could simply be put into a separate type as a database object. Thereby, the problem with conveyor functions is solved.

The next feature that we stumble upon is the non-standard behavior of versioned views.



Remember, I talked about the fact that objects are inherited and updated? So, it turned out that if you and I created a versioned view on a conditionally zero edition, by the fifth edition we noticed that we had inaccuracies in the comments. For example, I notice after myself that in a comment on a column I can swap two letters. Do not leave such an imperfection!



So, the usual comments command leads to the fact that our versioned view is updated in the current version. Because of this, all dependent packages fall apart, and how to deal with it? To do this, they wrote a certain script, which, when creating a new edition, will update the versioning view every time the next release is released. This does not carry a large load on the database dictionary, but if necessary, make minor corrections or, for example, issue new grants, we do not need to create a new edition



Well, the last such bug or feature ... It is not clear why, when changing not null, restrictions on the column of versioned views fell apart. That is, as soon as we say that our column of the base table should now have not null restrictions, the view falls apart even when using dbms redifinition. We could not defeat this thing in any way, perhaps readers have come across this, it will be interesting to find out if a solution has been found.







What would I like to say in conclusion? Edition-Based Redefinition is an effective technology for a real opportunity to roll a release or hotfix online, in user mode. We touched, felt, realized that organizing integration on one server, when not all schemes would move to use this technology, is real, not to mention that the versioned scheme can work on a dedicated server or on a separate container database.



And as an application, and an answer to the key question, โ€œis it possible in production?โ€ ... We hope that Edition-Based Redefinition will move sooner or later to all our projects, and perhaps this will be the last stop of our applications and guarantee a calm sleep of the developer responsible for installing the new release.



Actually, that's all. Thanks for your attention.



All Articles