1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 /******************************************************************************
19  * $Id: dbrm.h 1878 2013-05-02 15:17:12Z dcathey $
20  *
21  *****************************************************************************/
22 
23 /** @file
24  * class DBRM
25  */
26 
27 #ifndef DBRM_H_
28 #define DBRM_H_
29 
30 #include <unistd.h>
31 #include <sys/types.h>
32 #include <vector>
33 #include <set>
34 #include <string>
35 #include <boost/thread.hpp>
36 #include <boost/shared_array.hpp>
37 #include <boost/scoped_ptr.hpp>
38 
39 #include "brmtypes.h"
40 #include "messagequeue.h"
41 
42 #include "extentmap.h"
43 #include "vss.h"
44 #include "vbbm.h"
45 #include "copylocks.h"
46 #include "calpontsystemcatalog.h"
47 #include "sessionmanagerserver.h"
48 #include "configcpp.h"
49 #include "mastersegmenttable.h"
50 
51 #if defined(_MSC_VER) && defined(xxxDBRM_DLLEXPORT)
52 #define EXPORT __declspec(dllexport)
53 #else
54 #define EXPORT
55 #endif
56 
57 #ifdef BRM_DEBUG
58 #define DBRM_THROW
59 #else
60 #define DBRM_THROW throw()
61 #endif
62 
63 namespace BRM
64 {
65 
66 /** @brief The interface to the Distributed BRM system.
67  *
68  * There are 3 components of the Distributed BRM (DBRM).
69  * \li The interface
70  * \li The Master node
71  * \li Slave nodes
72  *
73  * The DBRM class is the interface, which is identical to the single-node
74  * version, the BlockResolutionManager class.
75  *
76  * The DBRM components effectively implement a networking & synchronization
77  * layer to the BlockResolutionManager class so that every node that needs
78  * BRM data always has an up-to-date copy of it locally.  An operation that changes
79  * BRM data is duplicated on all hosts that run a Slave node so that every
80  * node has identical copies.  All "read" operations are satisfied locally.
81  *
82  * Calpont configuration file entries are necessary for the interface, Master,
83  * and Slave to find each other.  Config file entries look like
84  * \code
85  * <DBRM_Controller>
86  *	<IPAddr>
87  * 	<Port>
88  *	<NumWorkers>N</NumWorkers>
89  * </DBRM_Controller>
90  * <DBRM_Worker1>
91  *	<IPAddr>
92  *	<Port>
93  * </DBRM_Worker1>
94  *	...
95  * <DBRM_WorkerN>
96  *	<IPAddr>
97  *	<Port>
98  * </DBRM_WorkerN>
99  * \endcode
100  */
101 
102 class DBRM
103 {
104 public:
105     // The param noBRMFcns suppresses init of the ExtentMap, VSS, VBBM, and CopyLocks.
106     // It can speed up init if the caller only needs the other structures.
107     EXPORT DBRM(bool noBRMFcns = false);
108     EXPORT ~DBRM();
109 
refreshShm()110     EXPORT static void refreshShm()
111     {
112         MasterSegmentTableImpl::refreshShm();
113         ExtentMapImpl::refreshShm();
114         FreeListImpl::refreshShm();
115     }
116 
117     // @bug 1055+ - Added functions below for multiple files per OID enhancement.
118 
119     /** @brief Get the OID, offset, db root, partition, and segment of a logical block ID.
120      *
121      * Get the OID, offset, db root, and partition of a logical block ID.
122      * @param lbid (in) The LBID to look up
123      * @param verid (in) The version of the LBID to look up
124      * @param vbFlags (in) If true, look for the block in the version buffer
125      * if false, the extent map
126      * @param oid (out) The OID of the file the LBID is allocated to
127      * @param fileBlockOffset (out) The file block offset of the LBID
128      * @param dbRoot (out) The DBRoot number that contains the file.
129      * @param partitionNum (out) The partition number for the file.
130      * @param segmentNum (out) The segment number for the file.
131      *
132      * @return 0 on success, non-0 on error (see brmtypes.h)
133      */
134     EXPORT int lookupLocal(LBID_t lbid, VER_t verid, bool vbFlag, OID_t& oid,
135                            uint16_t& dbRoot, uint32_t& partitionNum, uint16_t& segmentNum, uint32_t& fileBlockOffset) throw();
136 
137     /** @brief Get the LBID assigned to the given OID, block offset, partion, and segment.
138      *
139      * Get the LBID assigned to the given OID, block offset, partition, and segment.
140      * @param oid (in) The OID
141      * @param partitionNum (in) The partition number
142      * @parm segmentNum (in) The segment number
143      * @param fileBlockOffset (in) The offset in the OID to return the LBID of
144      * @param lbid (out) The LBID of the offset of the OID.
145      * @return 0 on success, non-0 on error (see brmtypes.h)
146      */
147     EXPORT int lookupLocal(OID_t oid, uint32_t partitionNum, uint16_t segmentNum, uint32_t fileBlockOffset, LBID_t& lbid) throw();
148 
149     /** @brief A dbroot-specific version of lookupLocal() */
150     EXPORT int lookupLocal_DBroot(OID_t oid, uint32_t dbroot,
151                                   uint32_t partitionNum, uint16_t segmentNum,
152                                   uint32_t fileBlockOffset, LBID_t& lbid) throw();
153     // @bug 1055-
154 
155     /** @brief Get the starting LBID assigned to the extent containing
156      *  the specified OID, block offset, partition, and segment.
157      *
158      * Get the LBID assigned to the given OID, partition, segment,
159      * and block offset.
160      * @param oid (in) The OID
161      * @param partitionNum (in) The partition number
162      * @parm segmentNum (in) The segment number
163      * @param fileBlockOffset (in) The requested offset in the specified OID
164      * @param lbid (out) The starting LBID of extent with specified offset
165      * @return 0 on success, non-0 on error (see brmtypes.h)
166      */
167     EXPORT int lookupLocalStartLbid(OID_t oid,
168                                     uint32_t partitionNum,
169                                     uint16_t segmentNum,
170                                     uint32_t fileBlockOffset,
171                                     LBID_t& lbid) throw();
172 
173     /**@brief Do a VSS lookup.
174      *
175      * Do a VSS lookup.  Gets the version ID of the block the caller should use
176      * and determines whether it is in the version buffer or the main database.
177      * @param lbid (in) The block number
178      * @param qc (in) The SCN & txn list provided by SessionManager::verID().
179      * @param txnID (in) If the caller has a transaction ID, put it here.
180      * Otherwise use 0.
181      * @param outVer (out) The version the caller should use.
182      * @param vbFlag (out) If true, the block is in the version buffer;
183      * false, the block is in the main database.
184      * @param vbOnly (in) If true, it will only consider entries in the Version Buffer
185      * (vbFlag will be true on return).  If false, it will also consider the main DB
186      * entries.  This defaults to false.
187      * @return 0 on success, non-0 on error (see brmtypes.h)
188      */
189     EXPORT int vssLookup(LBID_t lbid, const QueryContext& qc, VER_t txnID, VER_t* outVer,
190                          bool* vbFlag, bool vbOnly = false) throw();
191 
192     /** @brief Do many VSS lookups under one lock
193      *
194      * Do many VSS lookups under one lock.
195      * @param lbids (in) The LBIDs to look up
196      * @param qc (in) The input version info, equivalent to the verID param in vssLookup()
197      * @param txnID (in) The input transaction number, equivalent to the txnID param in vssLookup()
198      * @param out (out) The values equivalent to the out parameters in vssLookup() including the individual return codes, ordered as the lbid list.
199      * @return 0 on success, -1 on a fatal error.
200      */
201     EXPORT int bulkVSSLookup(const std::vector<LBID_t>& lbids, const QueryContext_vss& qc, VER_t txnID,
202                              std::vector<VSSData>* out);
203 
204     /// returns the version in the main DB files or 0 if none exist
205     EXPORT VER_t getCurrentVersion(LBID_t lbid, bool* isLocked = NULL) const;
206 
207     /// returns the highest version # in the version buffer, or -1 if none exist
208     EXPORT VER_t getHighestVerInVB(LBID_t lbid, VER_t max = std::numeric_limits<VER_t>::max()) const; // returns
209 
210     /// returns true if that block is in the version buffer, false otherwise including on error
211     EXPORT bool isVersioned(LBID_t lbid, VER_t version) const;
212 
213     /// Do many getCurrentVersion lookups under one lock grab
214     EXPORT int bulkGetCurrentVersion(const std::vector<LBID_t>& lbids, std::vector<VER_t>* versions,
215                                      std::vector<bool>* isLocked = NULL) const;
216 
217     /** @brief Get a complete list of LBIDs assigned to an OID
218      *
219      * Get a complete list of LBIDs assigned to an OID.
220      */
221     EXPORT int lookup(OID_t oid, LBIDRange_v& lbidList) throw();
222 
223     /** @brief Allocate a "stripe" of extents for columns in a table.
224      *
225      * Allocate a "stripe" of extents for the specified columns and DBRoot
226      * @param cols (in) List of column OIDs and column widths
227      * @param dbRoot (in) DBRoot for requested extents.
228      * @param partitionNum (in/out) Partition number in file path.
229      *        If allocating OID's first extent for this DBRoot, then
230      *        partitionNum is input, else it is an output arg.
231      * @param segmentNum (out) Segment number selected for new extents.
232      * @param extents (out) list of lbids, numBlks, and fbo for new extents
233      * @return 0 on success, -1 on error
234      */
235     EXPORT int createStripeColumnExtents(
236         const std::vector<CreateStripeColumnExtentsArgIn>& cols,
237         uint16_t  dbRoot,
238         uint32_t& partitionNum,
239         uint16_t& segmentNum,
240         std::vector<CreateStripeColumnExtentsArgOut>& extents) DBRM_THROW;
241 
242     /** @brief Allocate an extent for a column file
243      *
244      * Allocate a column extent for the specified OID and DBRoot.
245      * @param OID (in) The OID requesting the extent.
246      * @param colWidth (in) Column width of the OID.
247      * @param dbRoot (in) DBRoot where extent is to be added.
248      * @param partitionNum (in/out) Partition number in file path.
249      *        If allocating OID's first extent for this DBRoot, then
250      *        partitionNum is input, else it is an output arg.
251      * @param segmentNum (out) Segment number in file path.
252      * @param colDataType (in) the column type
253      * @param lbid (out) The first LBID of the extent created.
254      * @param allocdSize (out) The total number of LBIDs allocated.
255      * @param startBlockOffset (out) The first block of the extent created.
256      * @return 0 on success, -1 on error
257      */
258     // @bug 4091: To be deprecated.  Replaced by createStripeColumnExtents().
259     EXPORT int createColumnExtent_DBroot(OID_t oid,
260                                          uint32_t  colWidth,
261                                          uint16_t  dbRoot,
262                                          uint32_t& partitionNum,
263                                          uint16_t& segmentNum,
264                                          execplan::CalpontSystemCatalog::ColDataType colDataType,
265                                          LBID_t&    lbid,
266                                          int&       allocdSize,
267                                          uint32_t& startBlockOffset) DBRM_THROW;
268 
269     /** @brief Allocate extent for specified segment file
270      *
271      * Allocate column extent for the exact segment file
272      * specified by OID, DBRoot, partition, and segment.
273      * @param OID (in) The OID requesting the extent.
274      * @param colWidth (in) Column width of the OID.
275      * @param dbRoot (in) DBRoot where extent is to be added.
276      * @param partitionNum (in) Partition number in file path.
277      * @param segmentNum (in) Segment number in file path.
278      * @param lbid (out) The first LBID of the extent created.
279      * @param allocdSize (out) The total number of LBIDs allocated.
280      * @param startBlockOffset (out) The first block of the extent created.
281      * @return 0 on success, -1 on error
282      */
283     EXPORT int createColumnExtentExactFile(OID_t oid,
284                                            uint32_t  colWidth,
285                                            uint16_t  dbRoot,
286                                            uint32_t  partitionNum,
287                                            uint16_t  segmentNum,
288                                            execplan::CalpontSystemCatalog::ColDataType colDataType,
289                                            LBID_t&    lbid,
290                                            int&       allocdSize,
291                                            uint32_t& startBlockOffset) DBRM_THROW;
292 
293     /** @brief Allocate an extent for a dictionary store file
294      *
295      * Allocate a dictionary store extent for the specified OID, dbRoot,
296      * partition number, and segment number.
297      * @param OID (in) The OID requesting the extent.
298      * @param dbRoot (in) DBRoot to assign to the extent.
299      * @param partitionNum (in) Partition number to assign to the extent.
300      * @param segmentNum (in) Segment number to assign to the extent.
301      * @param colDataType (in) the column type
302      * @param lbid (out) The first LBID of the extent created.
303      * @param allocdSize (out) The total number of LBIDs allocated.
304      * @return 0 on success, -1 on error
305      */
306     EXPORT int createDictStoreExtent(OID_t oid,
307                                      uint16_t  dbRoot,
308                                      uint32_t  partitionNum,
309                                      uint16_t  segmentNum,
310                                      LBID_t&    lbid,
311                                      int&       allocdSize) DBRM_THROW;
312 
313     /** @brief Rollback (delete) set of column extents for specific OID & DBRoot
314      *
315      * Deletes all the extents that logically follow the specified
316      * column extent; and sets the HWM for the specified extent.
317      * @param oid OID of the extents to be deleted.
318      * @param bDeleteAll Indicates if all extents in the oid and dbroot are to
319      *        be deleted; else part#, seg#, and hwm are used.
320      * @param dbRoot DBRoot of the extents to be deleted.
321      * @param partitionNum Last partition to be kept.
322      * @param segmentNum Last segment in partitionNum to be kept.
323      * @param hwm HWM to be assigned to the last extent that is kept.
324      * @return 0 on success
325      */
326     EXPORT int rollbackColumnExtents_DBroot(OID_t oid,
327                                             bool      bDeleteAll,
328                                             uint16_t dbRoot,
329                                             uint32_t partitionNum,
330                                             uint16_t segmentNum,
331                                             HWM_t     hwm) DBRM_THROW;
332 
333     /** @brief Rollback (delete) a set of dict store extents for an OID & DBRoot
334      *
335      * Arguments specify the last stripe.  Any extents after this are
336      * deleted.  The hwm's of the extents in the last stripe are updated
337      * based on the contents of the hwm vector.  If hwms is a partial list,
338      * (as in the first stripe of a partition), then any extents in sub-
339      * sequent segment files for that partition are deleted.  if hwms is empty
340      * then all the extents in dbRoot are deleted.
341      * @param oid OID of the extents to be deleted or updated.
342      * @param dbRoot DBRoot of the extents to be deleted.
343      * @param partitionNum Last partition to be kept.
344      * @param segNums Vector of segment numbers for last partition to be kept.
345      * @param hwms Vector of hwms for the last partition to be kept.
346      * @return 0 on success
347      */
348     EXPORT int rollbackDictStoreExtents_DBroot(OID_t oid,
349             uint16_t dbRoot,
350             uint32_t partitionNum,
351             const std::vector<uint16_t>& segNums,
352             const std::vector<HWM_t>& hwms) DBRM_THROW;
353 
354     /** @brief delete of column extents for the specified extents.
355      *
356      * Deletes the extents from extent map
357      * @param extentInfo the information for extents
358      */
359     EXPORT int deleteEmptyColExtents(const std::vector<ExtentInfo>& extentsInfo) DBRM_THROW;
360 
361     /** @brief delete of dictionary extents for the specified extents.
362      *
363      * Deletes the extents from extent map
364      * @param extentInfo the information for extents
365      */
366     EXPORT int deleteEmptyDictStoreExtents(const std::vector<ExtentInfo>& extentsInfo) DBRM_THROW;
367 
368     /** @brief Delete the extents of an OID and invalidate VSS references to them
369      *
370      * Delete the extents assigned to an OID and deletes entries in the VSS
371      * that refer to the LBIDs used by it.
372      * @note The old version of this function deliberately did not delete the entries
373      * in the version buffer.
374      * @note This function is ridiculously slow right now.
375      * @param OID The OID of the object being deleted
376      * @return 0 on success, non-0 on error (see brmtypes.h)
377      */
378     EXPORT int deleteOID(OID_t oid) DBRM_THROW;
379 
380 
381     /** @brief Delete the extents of an OID and invalidate VSS references to them
382      *
383      * Delete the extents assigned to an OID and deletes entries in the VSS
384      * that refer to the LBIDs used by it.
385      * @note The old version of this function deliberately did not delete the entries
386      * in the version buffer.
387      * @note This function is ridiculously slow right now.
388      * @param OID The OID of the object being deleted
389      * @return 0 on success, non-0 on error (see brmtypes.h)
390      */
391     EXPORT int deleteOIDs( const std::vector<OID_t>& oids) DBRM_THROW;
392 
393     /** @brief Gets the last local high water mark for an OID and dbRoot
394      *
395      * Get last local high water mark of an OID for a given dbRoot, relative to
396      * a segment file. The partition and segment numbers for the pertinent
397      * segment are also returned.
398      * @param OID (in) The OID
399      * @param dbRoot (in) The relevant DBRoot
400      * @param partitionNum (out) The relevant partition number
401      * @param segmentNum (out) The relevant segment number
402      * @param hwm (out) Last local high water mark for specified input
403      * @param status (out) State of the extent (Available, OutOfService, etc)
404      * @param bFound (out) Indicates whether an extent was found on the dbRoot
405      * @return 0 on success, non-0 on error (see brmtypes.h)
406      */
407     EXPORT int getLastHWM_DBroot(int OID, uint16_t dbRoot,
408                                  uint32_t& partitionNum, uint16_t& segmentNum, HWM_t& hwm,
409                                  int& status, bool& bFound) throw();
410 
411     /** @brief Get the "high water mark" of an OID, partition, and segment
412      *
413      * Get local high water mark (aka, the highest numbered written block
414      * offset) for an OID,partition,segment relative to the segment file.
415      * This applies to either column or dictionary store OIDs.
416      * @param oid (in) The OID
417      * @param partitionNum (in) Relevant partition number.
418      * @param segmentNum (in) Relevant segment number.
419      * @param hwm (out) The high water mark of oid
420      * @param status (out) State of the extent (Available, OutOfService, etc)
421      * @return 0 on success, non-0 on error (see brmtypes.h)
422      */
423     EXPORT int getLocalHWM(OID_t oid, uint32_t partitionNum,
424                            uint16_t segmentNum, HWM_t& hwm, int& status) throw();
425 
426     /** @brief Set the "high water mark" of an OID, partition, and segment
427      *
428      * Set the local high water mark (aka, the highest numbered written
429      * block offset) for the segment file referenced by the specified OID,
430      * partition, and segment number.
431      * This applies to either column or dictionary store OIDs.
432      * @param oid (in) The OID
433      * @param partitionNum (in) Relevant partition number.
434      * @param segmentNum (in) Relevant segment number.
435      * @param hwm (in) The high water mark of oid
436      * @return 0 on success, non-0 on error (see brmtypes.h)
437      */
438     EXPORT int setLocalHWM(OID_t oid, uint32_t partitionNum,
439                            uint16_t segmentNum, HWM_t hwm) DBRM_THROW;
440 
441     EXPORT int bulkSetHWM(const std::vector<BulkSetHWMArg>&, VER_t transID = 0) DBRM_THROW;
442 
443     /** @brief Does setLocalHWM, casual partitioning changes, & commit.  The HWM &
444      * CP changes are atomic with this fcn.  All functionality is optional.  Passing
445      * in an empty vector for any of these parms makes it do nothing for the
446      * corresponding operation.
447      *
448      * It returns 0 if all operations succeed, -1 if any operation fails.
449      * The controllernode will undo all changes made on error.
450      */
451     EXPORT int bulkSetHWMAndCP(const std::vector<BulkSetHWMArg>& hwmArgs,
452                                const std::vector<CPInfo>& setCPDataArgs,
453                                const std::vector<CPInfoMerge>& mergeCPDataArgs,
454                                VER_t transID) DBRM_THROW;
455 
456     EXPORT int bulkUpdateDBRoot(const std::vector<BulkUpdateDBRootArg>&);
457 
458     /** @brief Get HWM information about last segment file for each DBRoot
459      *  assigned to a specific PM.
460      *
461      * Vector will contain an entry for each DBRoot.  If no "available" extents
462      * are found for a DBRoot, then totalBlocks will be 0 (and hwmExtentIndex
463      * will be -1) for that DBRoot.
464      * @param oid The oid of interest.
465      * @param pmNumber The PM number of interest.
466      * @param emDbRootHwmInfos The vector of DbRoot/HWM related objects.
467      */
468     EXPORT int getDbRootHWMInfo(OID_t oid, uint16_t pmNumber,
469                                 EmDbRootHWMInfo_v& emDbRootHwmInfos) throw();
470 
471     /** @brief Get the status (AVAILABLE, OUTOFSERVICE, etc) for the
472      * segment file represented by the specified OID, part# and seg#.
473      *
474      * Unlike many of the other DBRM functions, this function does
475      * not return a bad return code if no extent is found; the "found"
476      * flag indicates whether an extent was found or not.
477      *
478      * @param oid (in) The OID of interest
479      * @param partitionNum (in) The partition number of interest
480      * @param segmentNum (in) The segment number of interest
481      * @param bFound (out) Indicates if extent was found or not
482      * @param status (out) The state of the extents in the specified
483      *        segment file.
484      * @return 0 on success, non-0 on error (see brmtypes.h)
485      */
486     EXPORT int getExtentState(OID_t oid, uint32_t partitionNum,
487                               uint16_t segmentNum, bool& bFound, int& status) throw();
488 
489     /** @brief Gets the extents of a given OID
490      *
491      * Gets the extents of a given OID.
492      * @param OID (in) The OID to get the extents for.
493      * @param entries (out) A snapshot of the OID's Extent Map entries
494      * sorted by starting LBID; note that The Real Entries can change at
495      * any time.  Also, internally the size of an extent is measured in
496      * multiples of 1024 LBIDs.  So, if the size field is 10, it represents
497      * 10240 LBIDs.
498      * @param sorted (in) indicates if output is to be sorted
499      * @param notFoundErr (in) indicates if no extents is considered an err
500      * @param incOutOfService (in) include/exclude out of service extents
501      * @return 0 on success, non-0 on error (see brmtypes.h)
502      */
503     EXPORT int getExtents(int OID, std::vector<struct EMEntry>& entries,
504                           bool sorted = true, bool notFoundErr = true,
505                           bool incOutOfService = false);
506 
507     /** @brief Gets the extents of a given OID under specified dbroot
508      *
509      * Gets the extents of a given OID under specified dbroot.
510      * @param OID (in) The OID to get the extents for.
511      * @param entries (out) A snapshot of the OID's Extent Map entries
512      * @param dbroot (in) dbroot
513      * @return 0 on success, non-0 on error (see brmtypes.h)
514      */
515     EXPORT int getExtents_dbroot(int OID, std::vector<struct EMEntry>& entries,
516                                  const uint16_t dbroot) throw();
517 
518     /** @brief Gets the number of extents for the specified OID and DBRoot
519      *
520      * @param OID (in) The OID of interest
521      * @param dbroot (in) The DBRoot of interest
522      * @param incOutOfService (in) include/exclude out of service extents
523      * @param numExtents (out) number of extents found for OID and dbroot
524      * @return 0 on success, non-0 on error (see brmtypes.h)
525      */
526     EXPORT int getExtentCount_dbroot(int OID, uint16_t dbroot,
527                                      bool incOutOfService, uint64_t& numExtents) throw();
528 
529     /** @brief Gets the number of rows in an extent
530      *
531      * Gets the number of rows in an extent.
532      * @return The extent size
533      */
534 // dmc-getExtentSize() to be deprecated, replaced by getExtentRows()
535     EXPORT int getExtentSize() throw();
536     EXPORT unsigned getExtentRows() throw();
537 
538     /** @brief Gets the DBRoot for the specified system catalog OID
539      *
540      * Function should only be called for System Catalog OIDs, as it assumes
541      * the OID is fully contained on a single DBRoot, returning the first
542      * DBRoot found.  This only makes since for a System Catalog OID, because
543      * all other column OIDs can span multiple DBRoots.
544      *
545      * @param oid The system catalog OID
546      * @param dbRoot (out) the DBRoot holding the system catalog OID
547      */
548     EXPORT int getSysCatDBRoot(OID_t oid, uint16_t& dbRoot) throw();
549 
550     /** @brief Delete a Partition for the specified OID(s).
551      *
552      * @param OID (in) the OID of interest.
553      * @param partitionNums (in) the set of partitions to be deleted.
554      */
555     EXPORT int deletePartition(const std::vector<OID_t>& oids,
556                                const std::set<LogicalPartition>& partitionNums, std::string& emsg) DBRM_THROW;
557 
558     /** @brief Mark a Partition for the specified OID(s) as out of service.
559      *
560      * @param OID (in) the OID of interest.
561      * @param partitionNums (in) the set of partitions to be marked out of service.
562      */
563     EXPORT int markAllPartitionForDeletion(const std::vector<OID_t>& oids) DBRM_THROW;
564 
565     /** @brief Mark a Partition for the specified OID(s) as out of service.
566      *
567      * @param OID (in) the OID of interest.
568      * @param partitionNums (in) the set of partitions to be marked out of service.
569      */
570     EXPORT int markPartitionForDeletion(const std::vector<OID_t>& oids,
571                                         const std::set<LogicalPartition>& partitionNums, std::string& emsg) DBRM_THROW;
572 
573     /** @brief Restore a Partition for the specified OID(s).
574      *
575      * @param OID (in) the OID of interest.
576      * @param partitionNums (in) the set of partitions to be restored.
577      */
578     EXPORT int restorePartition(const std::vector<OID_t>& oids,
579                                 const std::set<LogicalPartition>& partitionNums, std::string& emsg) DBRM_THROW;
580 
581     /** @brief Get the list of out-of-service partitions for a given OID
582      *
583      * @param OID (in) the OID of interest.
584      * @param partitionNums (out) the out-of-service partitions for the oid.
585      * partitionNums will be in sorted order.
586      */
587     EXPORT int getOutOfServicePartitions(OID_t oid,
588                                          std::set<LogicalPartition>& partitionNums) throw();
589 
590     /** @brief Delete all rows in the extent map that reside on the given DBRoot
591      *
592      * @param dbroot (in) the dbroot to be deleted
593      */
594     EXPORT int deleteDBRoot(uint16_t dbroot) DBRM_THROW;
595 
596     /** @brief Is the specified DBRoot empty with no extents.
597      * Returns error if extentmap shared memory is not loaded.
598      *
599      * @param dbroot DBRoot of interest
600      * @param isEmpty (output) Flag indiicating whether DBRoot is empty
601      * @param errMsg  (output) Error message corresponding to bad return code
602      * @return ERR_OK on success
603      */
604     EXPORT int isDBRootEmpty(uint16_t dbroot,
605                              bool& isEmpty, std::string& errMsg) throw();
606 
607     /** @brief Registers a version buffer entry.
608      *
609      * Registers a version buffer entry at <vbOID, vbFBO> with
610      * values of <transID, lbid>.
611      * @note The version buffer locations must hold the 'copy' lock
612      * first.
613      * @return 0 on success, non-0 on error (see brmtypes.h)
614      */
615     EXPORT int writeVBEntry(VER_t transID, LBID_t lbid, OID_t vbOID,
616                             uint32_t vbFBO) DBRM_THROW;
617 
618     /** @brief Bulk registers a version buffer entry.
619      *
620      * Similar to writeVBEntry, but registers the version buffer
621      * entries in bulk for a list of lbids and vbFBOs, for a given
622      * transID and vbOID.
623      * @note The version buffer locations must hold the 'copy' lock
624      * first.
625      * @return 0 on success, non-0 on error (see brmtypes.h)
626      */
627     EXPORT int bulkWriteVBEntry(VER_t transID,
628                                 const std::vector<BRM::LBID_t>& lbids,
629                                 OID_t vbOID,
630                                 const std::vector<uint32_t>& vbFBOs) DBRM_THROW;
631 
632     /** @brief Retrieves a list of uncommitted LBIDs.
633      *
634      * Retrieves a list of uncommitted LBIDs for the given transaction ID.
635      * @param lbidList (out) On success this contains the ranges of LBIDs
636      * @return 0 on success, non-0 on error (see brmtypes.h)
637      */
638     EXPORT int getUncommittedLBIDs(VER_t transID,
639                                    std::vector<LBID_t>& lbidList)
640     throw();
641 
642     /** @brief Does what you think it does.
643      *
644      * @return 0 on success, non-0 on error (see brmtypes.h)
645      */
646     EXPORT int getDBRootsForRollback(VER_t transID, std::vector<uint16_t>* dbRootList)
647     throw();
648 
649     // @bug 1509.  Added getUncommittedExtentLBIDs function.
650     /** @brief Retrieves a list of uncommitted extent LBIDs.
651      *
652      * Retrieves a list of uncommitted LBIDs for the given transaction ID.
653      * This function differs from getUncommittedLBIDs in that only one LBID per
654      * extent is returned.  It is used to return a list that can be used to update
655      * casual partitioning information which is tracked at the extent level rather
656      * than the block level.
657      * @param lbidList (out) On success this contains the ranges of LBIDs
658      * @return 0 on success, non-0 on error (see brmtypes.h)
659      */
660     EXPORT int getUncommittedExtentLBIDs(VER_t transID, std::vector<LBID_t>& lbidList) throw();
661 
662     /** @brief Atomically prepare to copy data to the version buffer
663      *
664      * Atomically sets the copy flag on the specified LBID ranges
665      * and allocate blocks in the version buffer to copy them to.
666      * If any LBID in the range cannot be locked, none will be
667      * and this will return -1.
668      * @param transID The transaction ID doing the operation
669      * @param ranges (in) A list of LBID ranges that will be copied
670      * @param freeList (out) On success, a list of ranges of the version
671      * buffer blocks to copy the LBID range to.
672      * @note The caller must do a rollback or commit immediately after getting ERR_DEADLOCK (6).
673      * @return 0 on success, non-0 on error (see brmtypes.h)
674      */
675     EXPORT int beginVBCopy(VER_t transID, uint16_t dbRoot, const LBIDRange_v& ranges,
676                            VBRange_v& freeList) DBRM_THROW;
677 
678     /** @brief Atomically unset the copy lock & update the VSS.  Beware!  Read the warning!
679      *
680      * Atomically unset the copy lock for the specified LBID ranges
681      * and add a new locked VSS entry for each LBID in the range.
682      * @note The elements of the ranges parameter <b>MUST</b> be the
683      * same elements passed to beginVBCopy().  The number and order of the
684      * elements can be different, but every element in ranges must also
685      * have been an element in beginVBCopy's ranges.
686      * @return 0 on success, non-0 on error (see brmtypes.h)
687      */
688     EXPORT int endVBCopy(VER_t transID, const LBIDRange_v& ranges)
689     DBRM_THROW;
690 
691     /** @brief Commit the changes made for the given transaction.
692      *
693      * This unlocks the VSS entries with VerID = transID.
694      * @return 0 on success, non-0 on error (see brmtypes.h)
695      */
696     EXPORT int vbCommit(VER_t transID) DBRM_THROW;
697 
698     /** @brief Reverse the changes made during the given transaction.
699      *
700      * Record that the given LBID was reverted to version verID.
701      * @warning This removes the copy locks held on all ranges by transID.
702      * @param transID The transaction ID
703      * @param lbidList The list of ranges to rollback.
704      * @return 0 on success, non-0 on error (see brmtypes.h)
705      */
706     EXPORT int vbRollback(VER_t transID, const LBIDRange_v& lbidList)
707     DBRM_THROW;
708 
709     /** @brief Reverse the changes made during the given transaction.
710      *
711      * Record that the given LBID was reverted to version verID.
712      * @warning This removes the copy locks held on all ranges by transID.
713      * @param transID The transaction ID
714      * @param lbidList The list of singular LBIDs to rollback.
715      * @return 0 on success, non-0 on error (see brmtypes.h)
716      */
717     EXPORT int vbRollback(VER_t transID, const std::vector<LBID_t>& lbidList)
718     DBRM_THROW;
719 
720 
721     EXPORT int getUnlockedLBIDs(BlockList_t* list) DBRM_THROW;
722 
723     /** @brief Reinitialize the versioning data structures.
724      *
725      * This entry point empties the VSS and VBBM structures on the
726      * slave nodes.  At system startup and after recovery, the data left in
727      * the VSS and VBBM are unnecessary.  The primary purpose of this function
728      * is to free up memory.
729      * @return 0 on success, non-0 on error (see brmtypes.h).
730      */
731     EXPORT int clear() DBRM_THROW;
732 
733     /** @brief Check the consistency of each data structure
734      *
735      * Check the consistency of each data structure
736      * @return 0 on success, non-0 on error (see brmtypes.h)
737      */
738     EXPORT int checkConsistency() throw();
739 
740     /** @brief Get a list of the transactions currently in progress.
741      *
742      * Get a list of the transactions currently in progress.  This scans
743      * the copy locks & VSS for LBIDs that are locked by some transaction
744      * and stores the transaction ID.
745      *
746      * @param txnList Caller-supplied set to store the results in.
747      * @return 0 on success, non-0 on error (see brmtypes.h)
748      */
749     EXPORT int getCurrentTxnIDs(std::set<VER_t>& txnList) throw();
750 
751     /** @brief Persistence API.  Saves the local Extent Map to a file.
752      *
753      * Persistence API.  Saves the <b>local</b> Extent Map to a file.
754      *
755      * @param filename Relative or absolute path to save to.
756      * @return 0 on success, -1 on error
757      */
758     EXPORT int saveExtentMap(const std::string& filename) throw();
759 
760     /** @brief Persistence API.  Saves all BRM structures.
761      *
762      * Saves all <b>local</b> BRM structures to files.
763      *
764      * @param filename The filename prefix to use.  Saves 4 files with that prefix.
765      * @return 0 on success, -1 on error
766      */
767     EXPORT int saveState(std::string filename) throw();
768 
769     /** @brief Persistence API.  Saves all BRM structures using the filenames from Columnstore.xml.
770      *
771      * Saves all <b>local</b> BRM structures to files.
772      *
773      * @param filename The filename prefix to use.  Saves 4 files with that prefix.
774      * @return 0 on success, -1 on error
775      */
776     EXPORT int saveState() throw();
777 
778     /** @brief A function that forces the BRM to write a snapshot of its data structures to disk
779      *
780      * A function that forces the BRM to write a snapshot of its data structures to disk.
781      * This happens automatically after commits and rollbacks.  Bulk imports should call
782      * this fcn after an import.
783      *
784      * @return 0 on success, non-0 on error (see brmtypes.h).
785      */
786     EXPORT int takeSnapshot() throw();
787 
788     /* SessionManager interface */
789     EXPORT const QueryContext verID();
790     EXPORT const QueryContext sysCatVerID();
791     EXPORT const TxnID newTxnID(const SessionManagerServer::SID session, bool block,
792                                 bool isDDL = false);
793     EXPORT void committed(BRM::TxnID& txnid);
794     EXPORT void rolledback(BRM::TxnID& txnid);
795     EXPORT const BRM::TxnID getTxnID(const SessionManagerServer::SID session);
796     EXPORT boost::shared_array<SIDTIDEntry> SIDTIDMap(int& len);
797     EXPORT void sessionmanager_reset();
798 
799     /* Note, these pull #s from two separate sequences.  That is, they both
800     return 0, then 1, 2, 3, etc.  */
801     EXPORT uint32_t getUnique32();
802     EXPORT uint64_t getUnique64();
803 
804     /* New table lock interface */
805     /* returns a unique ID (> 0) for the lock on success, 0 on failure.
806      * Also, on failure, the ownerName, pid, and session ID parameters will be set
807      * to the owner of one of the overlapping locks. */
808     EXPORT uint64_t getTableLock(const std::vector<uint32_t>& pmList, uint32_t tableOID,
809                                  std::string* ownerName, uint32_t* ownerPID, int32_t* ownerSessionID,
810                                  int32_t* ownerTxnID, LockState state);
811     EXPORT bool releaseTableLock(uint64_t id);
812     EXPORT bool changeState(uint64_t id, LockState state);
813     EXPORT bool changeOwner(uint64_t id, const std::string& ownerName, uint32_t ownerPID,
814                             int32_t ownerSessionID, int32_t ownerTxnID);
815     EXPORT bool checkOwner(uint64_t id);
816     EXPORT std::vector<TableLockInfo> getAllTableLocks();
817     EXPORT void releaseAllTableLocks();
818     EXPORT bool getTableLockInfo(uint64_t id, TableLockInfo* out);
819 
820     /** Casual partitioning support **/
821     EXPORT int markExtentInvalid(const LBID_t lbid,
822                                  execplan::CalpontSystemCatalog::ColDataType colDataType) DBRM_THROW;
823     EXPORT int markExtentsInvalid(const std::vector<LBID_t>& lbids,
824                                   const std::vector<execplan::CalpontSystemCatalog::ColDataType>& colDataTypes) DBRM_THROW;
825     EXPORT int getExtentMaxMin(const LBID_t lbid, int64_t& max, int64_t& min, int32_t& seqNum) throw();
826 
827     EXPORT int setExtentMaxMin(const LBID_t lbid, const int64_t max, const int64_t min, const int32_t seqNum) DBRM_THROW;
828 
829     /** @brief Updates the max and min casual partitioning info for the passed extents.
830      *
831      * @bug 1970.
832      *
833      * @param cpInfos vector of CPInfo objects.  The firstLbid must be the first LBID in the extent.
834      * @return 0 on success, -1 on error
835      */
836     EXPORT int setExtentsMaxMin(const CPInfoList_t& cpInfos) DBRM_THROW;
837 
838     /** @brief Merges max/min casual partitioning info for the specified
839      *  extents, with the current CP info.
840      *
841      * @param cpInfos vector of CPInfo objects.  The Lbids must be the
842      * starting LBID in the relevant extent.
843      * @return 0 on success, -1 on error
844      */
845     EXPORT int mergeExtentsMaxMin(const CPInfoMergeList_t& cpInfos) DBRM_THROW;
846 
847     /* read-side interface for locking LBID ranges (used by PrimProc) */
848     EXPORT void lockLBIDRange(LBID_t start, uint32_t count);
849     EXPORT void releaseLBIDRange(LBID_t start, uint32_t count);
850 
851     /* write-side interface for locking LBID ranges (used by DML) */
852     EXPORT int dmlLockLBIDRanges(const std::vector<LBIDRange>& ranges, int txnID);
853     EXPORT int dmlReleaseLBIDRanges(const std::vector<LBIDRange>& ranges);
854 
855     /* OAM Interface */
856     EXPORT int halt() DBRM_THROW;
857     EXPORT int resume() DBRM_THROW;
858     EXPORT int forceReload() DBRM_THROW;
859     EXPORT int setReadOnly(bool b) DBRM_THROW;
860     EXPORT int isReadWrite() throw();
861 
862     EXPORT bool isEMEmpty() throw();
863 
864     EXPORT std::vector<InlineLBIDRange> getEMFreeListEntries() throw();
865 
866     /** @brief Check if the system is ready for updates
867      *
868      * Check is the system has completed rollback processing and is
869      * ready for updates
870      */
871     EXPORT int getSystemReady() throw();
872 
873     /** @brief Check if the system is ready for queries
874      *
875      * Check is the system has completed rollback processing and is
876      * ready for updates
877      */
878     EXPORT int getSystemQueryReady() throw();
879 
880     /** @brief Check if the system is suspended
881      *
882      * Suspended is caused by user at calpont-console
883      * @return 0 - system is not suspended, > 0 - system is
884      *  	   suspended, < 0 on error
885      */
886     EXPORT int getSystemSuspended() throw();
887 
888     /** @brief Check if system suspension is pending
889      *
890      * If the user at calpont-console asks for suspension, but ddl,
891      * dml or cpimport are running, then we can't suspend. If user
892      * says suspend when all work completed, then this flag is set
893      * to prevent new work from starting.
894      * @param bRollback (out) if true, system is in a rollback mode
895      *  		before suspension.
896      * @return 0 - system is not in a suspend pending state, > 0 -
897      *  	   system is in a suspend pending state, < 0 on error
898      */
899     EXPORT int getSystemSuspendPending(bool& bRollback) throw();
900 
901     /** @brief Check if system shutdown is pending
902      *
903      * If the user at calpont-console asks for shutdown, but ddl,
904      * dml or cpimport are running, then we can't shutdown. If user
905      * says shutdown when all work completed, then this flag is set
906      * to prevent new work from starting.
907      * @param bRollback (out) if true, system is in rollback mode
908      *  		before shutdown.
909      * @param bForce (out) if true, system is in force shutdown
910      *  		mode. No work of any kind should be done.
911      * @return 0 - system is not pending a shutdown, > 0 - system is
912      *  	   pending a shutdown, < 0 on error
913      */
914     EXPORT int getSystemShutdownPending(bool& bRollback, bool& bForce) throw();
915 
916     /** @brief Mark the system as ready for updates
917      *
918      * The system has completed rollback processing and is therefore ready for updates
919      * @param bReady the state the ready flag should be set to.
920      * @return < 0 on error
921      */
922     EXPORT int setSystemReady(bool bReady) throw();
923 
924     /** @brief Mark the system as ready for queries
925      *
926      * The system has completed bring up all modules and is ready for queries
927      * Queries are allowed during DMLRollback, so SS_READY won't fork for queries.
928      * @param bReady the state the ready flag should be set to.
929      * @return < 0 on error
930      */
931     EXPORT int setSystemQueryReady(bool bReady) throw();
932 
933     /** @brief Mark the system as suspended (or not)
934      *
935      * @param bSuspended the suspend state the system should be set
936      *   				to.
937      * @return < 0 on error
938      */
939     EXPORT int setSystemSuspended(bool bSuspended) throw();
940 
941     /** @brief Mark the system as suspension pending
942      *
943      * @param bPending the suspend pending state the system should
944      *  				be set to.
945      * @param bRollback if true, rollback all active transactions
946      *  				before full suspension of writes (only used
947      *  				if bPending is true).
948      * @return < 0 on error
949      */
950     EXPORT int setSystemSuspendPending(bool bPending, bool bRollback = false) throw();
951 
952     /** @brief Mark the system as shutdown pending
953      *
954      * @param bPending the suspend pending state the system should
955      *  				be set to.
956      * @param bRollback if true, rollback all active transactions
957      *  				before shutting down. (only used if bPending
958      *  				is true).
959      * @param bForce if true, we're shutting down now. No further
960      *  				work, including rollback, should be done.
961      *  				(only used if bPending is true).
962      * @return < 0 on error
963      */
964     EXPORT int setSystemShutdownPending(bool bPending, bool bRollback = false, bool bForce = false) throw();
965 
966     /** @brief get the flags in the system state bit map.
967      * @param stateFlags (out)
968      * @return < 0 on error
969     */
970     int getSystemState(uint32_t& stateFlags) throw();
971 
972     /** @brief set the flags in the system state bit map.
973      *
974      * sets the flags that are set in stateFlags leaving other flags undisturbed
975      * @param stateFlags (out)
976      * @return < 0 on error
977     */
978     int setSystemState(uint32_t stateFlags) throw();
979 
980     /** @brief set the flags in the system state bit map.
981      *
982      * Clears the flags that are set in stateFlags leaving other flags undisturbed
983      * @param stateFlags (out)
984      * @return < 0 on error
985     */
986     int clearSystemState(uint32_t stateFlags) throw();
987 
988     /** @brief Check to see if Controller Node is functioning
989     */
990     bool isDBRMReady() throw();
991 
992     /* OID Manager interface.  See oidserver.h for the API documentation. */
993     EXPORT int allocOIDs(int num);
994     EXPORT void returnOIDs(int start, int end);
995     EXPORT int oidm_size();
996     EXPORT int allocVBOID(uint32_t dbroot);
997     EXPORT int getDBRootOfVBOID(uint32_t vbOID);
998     EXPORT std::vector<uint16_t> getVBOIDToDBRootMap();
999 
1000     /* Autoincrement interface */
1001     EXPORT void startAISequence(uint32_t OID, uint64_t firstNum, uint32_t colWidth,
1002                                 execplan::CalpontSystemCatalog::ColDataType colDataType);
1003     EXPORT bool getAIRange(uint32_t OID, uint32_t count, uint64_t* firstNum);
1004     EXPORT bool getAIValue(uint32_t OID, uint64_t* value);
1005     EXPORT void resetAISequence(uint32_t OID, uint64_t value);
1006     EXPORT void getAILock(uint32_t OID);
1007     EXPORT void releaseAILock(uint32_t OID);
1008 
1009     /* Added to support unsigned */
1010     /** @brief Invalidate the casual partitioning for all uncommited
1011      *         extents.
1012      *
1013      * Either txnid or plbidList can be passed . Only one will be
1014      * used.
1015      * @param txnid (in) - The transaction for which to get the lbid
1016      *              list.
1017      * @param plbidList (in) - a list of lbids whose extents are to
1018      *               be invalidated. Only one lbid per extent should
1019      *               be in this list, such as returned in
1020      *               getUncommittedExtentLBIDs().
1021      * @return nothing.
1022     */
1023     EXPORT void invalidateUncommittedExtentLBIDs(execplan::CalpontSystemCatalog::SCN txnid,
1024             std::vector<LBID_t>* plbidList = NULL);
1025 
1026 private:
1027     DBRM(const DBRM& brm);
1028     DBRM& operator=(const DBRM& brm);
1029     int8_t send_recv(const messageqcpp::ByteStream& in,
1030                      messageqcpp::ByteStream& out) throw();
1031 
1032     void deleteAISequence(uint32_t OID);   // called as part of deleteOID & deleteOIDs
1033 
1034     boost::scoped_ptr<MasterSegmentTable> mst;
1035     boost::scoped_ptr<ExtentMap> em;
1036     boost::scoped_ptr<VBBM> vbbm;
1037     boost::scoped_ptr<VSS> vss;
1038     boost::scoped_ptr<CopyLocks> copylocks;
1039     messageqcpp::MessageQueueClient* msgClient;
1040     std::string masterName;
1041     boost::mutex mutex;
1042     config::Config* config;
1043     bool fDebug;
1044 };
1045 
1046 }
1047 
1048 #undef EXPORT
1049 
1050 #endif
1051