wire up the code to add index entries, mostly.
authorRobert Haas <[email protected]>
Fri, 1 Oct 2021 19:44:48 +0000 (15:44 -0400)
committerRobert Haas <[email protected]>
Fri, 1 Oct 2021 19:44:48 +0000 (15:44 -0400)
src/backend/access/conveyor/cbmodify.c
src/backend/access/conveyor/cbxlog.c
src/backend/access/conveyor/conveyor.c
src/include/access/cbmodify.h
src/include/access/cbxlog.h

index c5e5b7e070987cb631126efae332d8976d4b8204..f819b3ab443e7e9c67a102310dcde6a97c48efc7 100644 (file)
@@ -372,9 +372,11 @@ cb_allocate_index_page(RelFileNode *rnode,
  * Relocate index entries from the metapage to a page in an index segment,
  * and optionally write XLOG for the change.
  *
- * 'pageno' is the logical page number for the first index entry that we're
- * relocating. It is needed to figure out where to place the index entries
- * on the index page.
+ * 'pageoffset' is the offset within the index page where the new entries
+ * should be placed.
+ *
+ * 'index_page_start' is the first logical page number covered by the index
+ * page being modified.
  *
  * See cb_xlog_allocate_index_segment for the corresponding REDO routine.
  */
@@ -387,6 +389,7 @@ cb_relocate_index_entries(RelFileNode *rnode,
                                                  unsigned pageoffset,
                                                  unsigned num_index_entries,
                                                  CBSegNo *index_entries,
+                                                 CBPageNo index_page_start,
                                                  bool needs_xlog)
 {
        Page            metapage;
@@ -400,6 +403,10 @@ cb_relocate_index_entries(RelFileNode *rnode,
 
        START_CRIT_SECTION();
 
+       /* If these are the first entries on the page, initialize it. */
+       if (pageoffset == 0)
+               cb_indexpage_initialize(indexpage, index_page_start);
+
        cb_indexpage_add_index_entries(indexpage, pageoffset, num_index_entries,
                                                                   index_entries);
        cb_metapage_remove_index_entries(meta, num_index_entries, true);
@@ -408,15 +415,19 @@ cb_relocate_index_entries(RelFileNode *rnode,
        {
                xl_cb_relocate_index_entries xlrec;
                XLogRecPtr      lsn;
+               uint8           flags = REGBUF_STANDARD;
 
                xlrec.pageoffset = pageoffset;
                xlrec.num_index_entries = num_index_entries;
+               xlrec.index_page_start = index_page_start;
+
+               if (pageoffset == 0)
+                       flags |= REGBUF_WILL_INIT;
 
                XLogBeginInsert();
                XLogRegisterBlock(0, rnode, fork, CONVEYOR_METAPAGE, metapage,
                                                  REGBUF_STANDARD);
-               XLogRegisterBlock(1, rnode, fork, indexblock, indexpage,
-                                                 REGBUF_STANDARD);
+               XLogRegisterBlock(1, rnode, fork, indexblock, indexpage, flags);
                XLogRegisterData((char *) &xlrec, SizeOfCBRelocateIndexEntries);
                XLogRegisterData((char *) index_entries,
                                                 num_index_entries * sizeof(CBSegNo));
index e9d32ee870db529e486508976b8890478246cec4..5b18506786a65f3221bcf810ce2437b81a07bd84 100644 (file)
@@ -223,6 +223,9 @@ cb_xlog_relocate_index_entries(XLogReaderState *record)
        {
                Page    indexpage = BufferGetPage(indexbuffer);
 
+               if (xlrec->pageoffset == 0)
+                       cb_indexpage_initialize(indexpage, xlrec->index_page_start);
+
                cb_indexpage_add_index_entries(indexpage, xlrec->pageoffset,
                                                                           xlrec->num_index_entries,
                                                                           xlrec->index_entries);
index b137f513fe0d01939b937c927f46195850c70e64..2c932d0f22f8a85a6a83d4e97aa050ba6524dcb7 100644 (file)
@@ -169,6 +169,7 @@ ConveyorBeltGetNewPage(ConveyorBelt *cb, CBPageNo *pageno)
        bool            needs_xlog;
        int                     mode = BUFFER_LOCK_SHARE;
        int                     iterations_without_next_pageno_change = 0;
+       unsigned        lppip;
 
        /*
         * It would be really bad if someone called this function a second time
@@ -178,6 +179,9 @@ ConveyorBeltGetNewPage(ConveyorBelt *cb, CBPageNo *pageno)
        Assert(!BufferIsValid(cb->cb_insert_metabuffer));
        Assert(!BufferIsValid(cb->cb_insert_buffer));
 
+       /* Logical pages per index segment, and per index page. */
+       lppip = cb_logical_pages_per_index_page(cb->cb_pages_per_segment);
+
        /* Do any changes we make here need to be WAL-logged? */
        needs_xlog = RelationNeedsWAL(cb->cb_rel) || cb->cb_fork == INIT_FORKNUM;
 
@@ -398,6 +402,31 @@ ConveyorBeltGetNewPage(ConveyorBelt *cb, CBPageNo *pageno)
                        free_segno = CB_INVALID_SEGMENT;
                }
 
+               /*
+                * If we need to relocate index entries and if we have a lock on the
+                * correct index block, then go ahead and do it.
+                */
+               if (insert_state == CBM_INSERT_NEEDS_INDEX_ENTRIES_RELOCATED &&
+                       next_blkno == indexblock)
+               {
+                       unsigned        pageoffset;
+                       unsigned        num_index_entries;
+                       CBSegNo    *index_entries;
+                       CBPageNo        index_page_start;
+
+                       pageoffset = index_metapage_start % lppip;
+                       num_index_entries = Min(CB_METAPAGE_INDEX_ENTRIES,
+                                                                       CB_INDEXPAGE_INDEX_ENTRIES - pageoffset);
+                       index_entries = cb_metapage_get_index_entry_pointer(meta);
+                       index_page_start = index_metapage_start -
+                               pageoffset * cb->cb_pages_per_segment;
+                       cb_relocate_index_entries(cb->cb_insert_relfilenode, cb->cb_fork,
+                                                                         metabuffer, indexblock, indexbuffer,
+                                                                         pageoffset, num_index_entries,
+                                                                         index_entries, index_page_start,
+                                                                         needs_xlog);
+               }
+
                /* Release buffer locks and, except for the metapage, also pins. */
                LockBuffer(metabuffer, BUFFER_LOCK_UNLOCK);
                if (BufferIsValid(indexbuffer))
@@ -503,12 +532,18 @@ ConveyorBeltGetNewPage(ConveyorBelt *cb, CBPageNo *pageno)
                }
 
                /*
-                * If the metapage has no more space for index entries, we must move
-                * some of the existing entries to an index segment.
+                * If the metapage has no more space for index entries, but there's
+                * an index segment into which some of the existing ones could be
+                * moved, then cb_metapage_get_insert_state will have set next_blkno
+                * to the point to the block to which index entries should be moved.
                 */
                if (insert_state == CBM_INSERT_NEEDS_INDEX_ENTRIES_RELOCATED)
                {
-                       elog(ERROR, "XXX relocating index entries is not implemented yet");
+                       /* XXX this is bugged because it doesn't know about maybe
+                        * needing to extend the relation */
+                       indexblock = next_blkno;
+                       indexbuffer = ReadBufferExtended(cb->cb_rel, cb->cb_fork,
+                                                                                        indexblock, RBM_NORMAL, NULL);
                }
 
                /*
@@ -524,7 +559,8 @@ ConveyorBeltGetNewPage(ConveyorBelt *cb, CBPageNo *pageno)
                {
                        prevblock = cb_segment_to_block(cb->cb_pages_per_segment,
                                                                                        newest_index_segment, 0);
-                       prevbuffer = ConveyorBeltRead(cb, next_blkno, BUFFER_LOCK_SHARE);
+                       prevbuffer = ReadBufferExtended(cb->cb_rel, cb->cb_fork,
+                                                                                       prevblock, RBM_NORMAL, NULL);
                }
 
                /*
index 60f015f37e38f0798b8258da8490893f611c6fb3..f321bd1f9074812a46b214e3d06dee90f3ada3bc 100644 (file)
@@ -85,6 +85,7 @@ extern void cb_relocate_index_entries(RelFileNode *rnode,
                                                                          unsigned pageoffset,
                                                                          unsigned num_index_entries,
                                                                          CBSegNo *index_entries,
+                                                                         CBPageNo index_page_start,
                                                                          bool needs_xlog);
 
 #endif                                                 /* CBMODIFY_H */
index c55e75a1562612f7d7a2fb934a9bafd927df10ef..d2a10975f4d258493d3788b0cca7f24cec8cfb12 100644 (file)
@@ -56,6 +56,7 @@ typedef struct xl_cb_relocate_index_entries
 {
        unsigned        pageoffset;
        unsigned        num_index_entries;
+       CBPageNo        index_page_start;
        CBSegNo         index_entries[FLEXIBLE_ARRAY_MEMBER];
 } xl_cb_relocate_index_entries;