WL#9141: InnoDB: Refactor uncompressed BLOB code to facilitate partial fetch/update
Affects: Server-8.0
—
Status: Complete
Introduction: ============= This is a sub worklog of "WL#8960 InnoDB: Partial Fetch and Update of BLOB". This worklog is the second sub worklog followed by "WL#8985 InnoDB: Refactor compressed BLOB code to facilitate partial fetch/update". The purpose of this worklog is to refactor current code so that new BLOB features can be added conveniently. This worklog does to uncompressed BLOB similar to what WL#8985 did to compressed BLOB code. Logical Changes: ================ . The functionality of uncompressed BLOB is provided by C-style functions. This will be converted to C++ classes, structs and member functions. . The BLOB code will be isolated and kept in lob0lob.h and lob0lob.cc files. This will help in modular development of BLOB features. . All references will now be LOB (large objects). Detailed Changes: ================= . Introduced new module named lob. It contains lob/lob0lob.cc and include/lob0lob.h files. . Added new namespace lob. . lob::Inserter - a new class to insert a complete uncompressed BLOB. . lob::zInserter - a new class to insert a complete compressed BLOB. . lob::InsertContext - a new class to contain contextual information for the insert operation. . lob::BaseInserter - a class that holds common state and functions useful for both compressed and uncompressed BLOB. This is the base class for lob::Inserter and lob::zInserter. . lob::Deleter - a new class to destory/delete a BLOB (both compressed/uncompressed) . lob::DeleteContext - a new class to contain contextual information for the delete operation . lob::Reader - a new class to fetch a uncompressed BLOB. . lob::zReader - a new class to fetch a compressed BLOB. . lob::ReaderContext - a new class to contain contextual information for the fetch operation Design Rationale: ================= There are 2 approaches that I explored - one is to have a single LOB class with each major operations as an member function. For example, class LOB { public: int insert(); int update(); int read(); // .. private: // ... Context* m_ctx; }; But doing it this way, will make the class LOB like a kitchen sink. It will end up that some member variables are used only when we are doing insert operation, and some other member variables are used when doing read operation and so on. There won't be any cohesion b/w the member variables and member functions. For one instance of the LOB class, we will most likely use only one operation, eg insert. This is the reason I didn't prefer this approach. The other approach is to design LOB classes around the major operations that will be performed, which truely reflects the way these classes will be used. The current design of LOB classes revolves around the way the major operations that will be performed on LOB data. The currently supported major operations are insert, delete and read. As of now all of them operate on complete LOB data. For each of the major operation one new class is introduced. Inserter - for inserting LOB data. Reader - for reading LOB data. Deleter - for deleting LOB data. Now there are two variants to LOB data - compressed and uncompressed. An insert operation or a read operation is completely depended on whether the data is compressed or not. But a delete operation is not that much dependant on this. Hence I introduced separate classes for compressed LOB. Inserter - for inserting uncompressed LOB data. zInserter - for inserting compressed LOB data. Reader - for reading uncompressed LOB data. zReader - for reading compressed LOB data. Deleter - for deleting both compressed and uncompressed LOB data. At this point I noticed that there was some common code between Inserter and zInserter which I can factor out into a base class. So I introduced BaseInserter which will contain common state and function useful for both Inserter and zInserter. So the final list of main LOB classes are: Inserter - for inserting uncompressed LOB data. zInserter - for inserting compressed LOB data. BaseInserter - a base class containing common state and functions useful for both Inserter and zInserter. Inserter and zInserter derives from this base class. Reader - for reading uncompressed LOB data. zReader - for reading compressed LOB data. Deleter - for deleting both compressed and uncompressed LOB data. One point to be noted is that these classes are formed by refactoring existing code. So to reduce the amount of code changes, I allowed some differences in the way they operate. The Inserter and zInserter class is designed to insert all the LOB data of a single clustered index record. It operates on the big record vector. But the other classes (Reader, Deleter, zReader) all operate on a single LOB data only. By doing it this way, I avoid significant amount of code changes. The main classes of the LOB module has been identified above. To support them there was a need to provide context classes that will contain information needed for LOB operation. Previously, the C style functions had a list of 6 or 7 arguments. These arguments are the context information that is necessary to provide the various main operations on LOB data. For each main operation, the context information is identified separately. They are as follows: InsertContext - context information for doing insert of LOB. ` DeleteContext - context information for doing delete of LOB. ` ReadContext - context information for doing fetch of LOB. ` The insert operation also has one special optimization - the bulk insert. These context classes evolved separately as I refactored one operation at a time. And when I look back, I don't see any need to club them all together. There are some specific checks that are done only for the insert operation, like the redo log space check, which are captured in the InsertContext. If we have a single context class, then it will contain unnecessary information not usable for the current operation. Also, all these context classes are arrived at based on how and where it will be used. Finally, while evaluating this design, please do keep in mind that these classes come out of refactoring existing code. If you look at the patch, the amount of code changed where LOB module is _used_ is very minimal. I think my main focus was to isolate the LOB code and design a set of C++ classes which will make the extension of functionality easier. And the main purpose of refactoring was to enable to add partial fetch and partial modify/update operations. For these purposes, I believe that this design is suitable. Surely one can do more and more refactoring to achieve better results. But since we are doing refactoring for a particular purpose, I think we should stop when our purpose will be solved. Functions Removed: ================== The following functions has been removed. . btr_copy_blob_prefix() . btr_copy_externally_stored_field_prefix_low_func() Functions Moved to lob module: ============================== The following functions are moved to the lob module. . btr_copy_externally_stored_field_prefix_func() and the associated macros. . btr_rec_free_updated_extern_fields() . btr_blob_get_part_len() . btr_blob_get_next_page_no() . btr_check_blob_fil_page_type() . btr_rec_free_externally_stored_fields() . btr_copy_externally_stored_field_prefix_func() . btr_copy_externally_stored_field_func()
There is no functionality changes done in this worklog. There are no functional and non-functional requirements. Just ensure that there are no performance regressions because of this code refactoring.
This worklog will isolate the LOB code into a separate module. The following will be the interface to make use of LOB. lob::Inserter - a class to insert uncompressed large object (LOB). lob::Reader - a class to fetch uncompressed LOB. lob::Deleter - a class to free/delete both compressed/uncompressed LOB. lob::zInserter - a class to insert compressed LOB. lob::zReader - a class to fetch compressed LOB. For each of the LOB operations described above there is an associated context object. They are listed here: lob::InserterContext - a context object for insert operation. lob::ReaderContext - a context object for fetch/read operation. lob::DeleterContext - a context object for delete/free operation. A new namespace lob has been introduced that enclose all large object (LOB) classes, structs, enums and functions.
Copyright (c) 2000, 2024, Oracle Corporation and/or its affiliates. All rights reserved.