void itc_adaptive_read_inc (it_cursor_t * itc, buffer_desc_t * dest_buf) { page_map_t * map = dest_buf->bd_content_map; if (!dest_buf->bd_readers && map && BUF_SEEMS_LEAF (dest_buf, map)) { BD_SET_IS_WRITE (dest_buf, 1); itc->itc_dive_mode = PA_WRITE; } else dest_buf->bd_readers++; }
int DBGP_NAME (page_wait_access) (DBGP_PARAMS it_cursor_t * itc, dp_addr_t dp, buffer_desc_t * buf_from, buffer_desc_t ** buf_ret, int mode, int max_change) { buffer_desc_t decoy; buffer_desc_t *buf; dp_addr_t phys_dp; itc->itc_to_reset = RWG_NO_WAIT; itc->itc_max_transit_change = max_change; itc->itc_must_kill_trx = 0; if (!dp) GPF_T1 ("Zero DP in page_fault_map_sem"); if (buf_from) { ITC_IN_TRANSIT (itc, dp, buf_from->bd_page); } else ASSERT_IN_MAP (itc->itc_tree, dp); buf = IT_DP_TO_BUF (itc->itc_tree, dp); if (!buf) { ra_req_t * ra = NULL; IT_DP_REMAP (itc->itc_tree, dp, phys_dp); #ifdef MTX_DEBUG em_check_dp (itc->itc_tree->it_extent_map, phys_dp); if (phys_dp != dp) em_check_dp (itc->itc_tree->it_extent_map, dp); #endif if ((DP_DELETED == phys_dp || dbs_is_free_page (itc->itc_tree->it_storage, phys_dp)) && !strchr (wi_inst.wi_open_mode, 'a')) { log_error ("Reference to page with free remap dp = %ld, remap = %ld", (long) phys_dp, (long) dp); if (0 && DBS_PAGE_IN_RANGE (itc->itc_tree->it_storage, phys_dp)) dbs_page_allocated (itc->itc_tree->it_storage, phys_dp); else { *buf_ret = PF_OF_DELETED; itc->itc_must_kill_trx = 1; itc->itc_to_reset = RWG_WAIT_ANY; ITC_LEAVE_MAPS (itc); return RWG_WAIT_ANY; } } memset (&decoy, 0, sizeof (buffer_desc_t)); decoy.bd_being_read = 1; if (PA_READ == mode) decoy.bd_readers = 1; else BD_SET_IS_WRITE (&decoy, 1); sethash (DP_ADDR2VOID (dp), &IT_DP_MAP (itc->itc_tree, dp)->itm_dp_to_buf, (void*)&decoy); ITC_LEAVE_MAPS (itc); buf = bp_get_buffer (NULL, BP_BUF_REQUIRED); is_read_pending++; buf->bd_being_read = 1; buf->bd_page = dp; buf->bd_storage = itc->itc_tree->it_storage; buf->bd_physical_page = phys_dp; BD_SET_IS_WRITE (buf, 0); buf->bd_write_waiting = NULL; if (buf_from && !itc->itc_landed) ra = itc_read_aside (itc, buf_from, dp); itc->itc_n_reads++; ITC_MARK_READ (itc); buf->bd_tree = itc->itc_tree; buf_disk_read (buf); is_read_pending--; if (ra) itc_read_ahead_blob (itc, ra, RAB_SPECULATIVE); if (buf_from) { ITC_IN_TRANSIT (itc, dp, buf_from->bd_page) } else
buffer_desc_t * it_new_page (index_tree_t * it, dp_addr_t addr, int type, int in_pmap, it_cursor_t * has_hold) { it_map_t * itm; extent_map_t * em = it->it_extent_map; int ext_type = (!it->it_blobs_with_index && (DPF_BLOB == type || DPF_BLOB_DIR == type)) ? EXT_BLOB : EXT_INDEX, n_tries; buffer_desc_t *buf; buffer_pool_t * action_bp = NULL; dp_addr_t physical_dp; if (in_pmap) GPF_T1 ("do not call isp_new_page in page map"); physical_dp = em_new_dp (em, ext_type, addr, NULL); if (!physical_dp) { log_error ("Out of disk space for database"); if (DPF_INDEX == type) { /* a split must never fail to get a page. Use the remap hold as a backup */ physical_dp = em_new_dp (it->it_extent_map, EXT_REMAP, 0, &has_hold->itc_n_pages_on_hold); if (!physical_dp) { log_error ("After running out of disk, cannot get a page from remap reserve to complete operation. Exiting."); call_exit (-1); } } else return NULL; } if (DPF_INDEX == type) it->it_n_index_est++; else it->it_n_blob_est++; for (n_tries = 0; ; n_tries++) { buf = bp_get_buffer_1 (NULL, &action_bp, in_log_replay ? BP_BUF_REQUIRED : BP_BUF_IF_AVAIL); if (buf) break; if (action_bp) bp_delayed_stat_action (action_bp); action_bp = NULL; if (n_tries > 10) { log_error ("Signaling out of disk due to failure to get a buffer. This condition is not a case of running out of disk"); return NULL; } if (5 == n_tries) log_info ("Failed to get a buffer for a new page. Retrying. If the failure repeats, an out of disk error will be signalled. The cause of this is having too many buffers wired down for preread, flush or group by/hash join temp space. To correct, increase the number of buffers in the configuration file. If this repeats in spite of having hundreds of thousands of buffers, please report to support."); if (n_tries > 4) virtuoso_sleep (0, 50000 * (n_tries - 4)); } if (action_bp) bp_delayed_stat_action (action_bp); if (buf->bd_readers != 1) GPF_T1 ("expecting buf to be wired down when allocated"); buf_dbg_printf (("Buf %x new in tree %x dp=%d\n", buf, isp, physical_dp)); itm = IT_DP_MAP (it, physical_dp); mutex_enter (&itm->itm_mtx); sethash (DP_ADDR2VOID (physical_dp), &itm->itm_dp_to_buf, (void*) buf); sethash (DP_ADDR2VOID (physical_dp), &itm->itm_remap, DP_ADDR2VOID (physical_dp)); buf->bd_page = physical_dp; buf->bd_physical_page = physical_dp; buf->bd_tree = it; buf->bd_storage = it->it_storage; buf->bd_pl = NULL; buf->bd_readers = 0; BD_SET_IS_WRITE (buf, 1); mutex_leave (&itm->itm_mtx); if (em != em->em_dbs->dbs_extent_map && EXT_INDEX == ext_type) { mutex_enter (em->em_mtx); remhash (DP_ADDR2VOID(physical_dp), em->em_uninitialized); mutex_leave (em->em_mtx); } #ifdef PAGE_TRACE memset (buf->bd_buffer, 0, PAGE_SZ); /* all for debug view */ #else memset (buf->bd_buffer, 0, PAGE_SZ - PAGE_DATA_SZ); /* header only */ #endif SHORT_SET (buf->bd_buffer + DP_FLAGS, type); if (type == DPF_INDEX) { page_map_t * map = buf->bd_content_map; if (!map) buf->bd_content_map = (page_map_t*) resource_get (PM_RC (PM_SZ_1)); else { if (map->pm_size > PM_SZ_1) { resource_store (PM_RC (map->pm_size), (void*) map); buf->bd_content_map = (page_map_t *) resource_get (PM_RC (PM_SZ_1)); } } pg_map_clear (buf); LONG_SET (buf->bd_buffer + DP_KEY_ID, it->it_key ? it->it_key->key_id : KI_TEMP); } else if (buf->bd_content_map) { resource_store (PM_RC (buf->bd_content_map->pm_size), (void*) buf->bd_content_map); buf->bd_content_map = NULL; } buf_set_dirty (buf); DBG_PT_PRINTF (("New page L=%d B=%p FL=%d K=%s \n", buf->bd_page, buf, type, it->it_key ? (it->it_key->key_name ? it->it_key->key_name : "unnamed key") : "no key")); TC (tc_new_page); return buf; }