mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-08 05:52:55 +00:00
Fix list_rels and list_nonrels in layeredRepository - return only visible objects
This commit is contained in:
@@ -589,7 +589,7 @@ impl Timeline for LayeredTimeline {
|
|||||||
let mut all_rels = HashSet::new();
|
let mut all_rels = HashSet::new();
|
||||||
let mut timeline = self;
|
let mut timeline = self;
|
||||||
loop {
|
loop {
|
||||||
let rels = timeline.layers.lock().unwrap().list_rels(spcnode, dbnode)?;
|
let rels = timeline.layers.lock().unwrap().list_rels(spcnode, dbnode, lsn)?;
|
||||||
|
|
||||||
all_rels.extend(rels.iter());
|
all_rels.extend(rels.iter());
|
||||||
|
|
||||||
@@ -601,26 +601,6 @@ impl Timeline for LayeredTimeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have a list of all rels that appeared anywhere in the history. Filter
|
|
||||||
// out relations that were dropped.
|
|
||||||
//
|
|
||||||
// FIXME: We should pass the LSN argument to the calls above, and avoid scanning
|
|
||||||
// dropped relations in the first place.
|
|
||||||
let mut res: Result<()> = Ok(());
|
|
||||||
all_rels.retain(
|
|
||||||
|reltag| match self.get_rel_exists(RelishTag::Relation(*reltag), lsn) {
|
|
||||||
Ok(exists) => {
|
|
||||||
info!("retain: {} -> {}", *reltag, exists);
|
|
||||||
exists
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
res = Err(err);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
res?;
|
|
||||||
|
|
||||||
Ok(all_rels)
|
Ok(all_rels)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,24 +623,6 @@ impl Timeline for LayeredTimeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have a list of all nonrels that appeared anywhere in the history. Filter
|
|
||||||
// out dropped ones.
|
|
||||||
//
|
|
||||||
// FIXME: We should pass the LSN argument to the calls above, and avoid scanning
|
|
||||||
// dropped relations in the first place.
|
|
||||||
let mut res: Result<()> = Ok(());
|
|
||||||
all_rels.retain(|tag| match self.get_rel_exists(*tag, lsn) {
|
|
||||||
Ok(exists) => {
|
|
||||||
info!("retain: {} -> {}", *tag, exists);
|
|
||||||
exists
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
res = Err(err);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
res?;
|
|
||||||
|
|
||||||
Ok(all_rels)
|
Ok(all_rels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -204,34 +204,57 @@ impl LayerMap {
|
|||||||
NUM_ONDISK_LAYERS.dec();
|
NUM_ONDISK_LAYERS.dec();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_rels(&self, spcnode: u32, dbnode: u32) -> Result<HashSet<RelTag>> {
|
// List relations that exist at the lsn
|
||||||
|
pub fn list_rels(&self, spcnode: u32, dbnode: u32, lsn: Lsn) -> Result<HashSet<RelTag>> {
|
||||||
let mut rels: HashSet<RelTag> = HashSet::new();
|
let mut rels: HashSet<RelTag> = HashSet::new();
|
||||||
|
|
||||||
for (seg, _entry) in self.segs.iter() {
|
for (seg, segentry) in self.segs.iter() {
|
||||||
if let RelishTag::Relation(reltag) = seg.rel {
|
if let RelishTag::Relation(reltag) = seg.rel {
|
||||||
// FIXME: skip if it was dropped before the requested LSN. But there is no
|
|
||||||
// LSN argument
|
|
||||||
|
|
||||||
if (spcnode == 0 || reltag.spcnode == spcnode)
|
if (spcnode == 0 || reltag.spcnode == spcnode)
|
||||||
&& (dbnode == 0 || reltag.dbnode == dbnode)
|
&& (dbnode == 0 || reltag.dbnode == dbnode)
|
||||||
{
|
{
|
||||||
rels.insert(reltag);
|
|
||||||
|
// Add only if it exists at the requested LSN.
|
||||||
|
if let Some(open) = &segentry.open {
|
||||||
|
if open.get_end_lsn() > lsn {
|
||||||
|
rels.insert(reltag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if let Some((_k, _v)) = segentry
|
||||||
|
.historic
|
||||||
|
.range((Included(Lsn(0)), Included(lsn)))
|
||||||
|
.next_back()
|
||||||
|
{
|
||||||
|
rels.insert(reltag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(rels)
|
Ok(rels)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_nonrels(&self, _lsn: Lsn) -> Result<HashSet<RelishTag>> {
|
// List non-relation relishes that exist at the lsn
|
||||||
|
pub fn list_nonrels(&self, lsn: Lsn) -> Result<HashSet<RelishTag>> {
|
||||||
let mut rels: HashSet<RelishTag> = HashSet::new();
|
let mut rels: HashSet<RelishTag> = HashSet::new();
|
||||||
|
|
||||||
// Scan the timeline directory to get all rels in this timeline.
|
// Scan the timeline directory to get all rels in this timeline.
|
||||||
for (seg, _entry) in self.segs.iter() {
|
for (seg, segentry) in self.segs.iter() {
|
||||||
// FIXME: skip if it was dropped before the requested LSN.
|
if let RelishTag::Relation(_) = seg.rel { }
|
||||||
|
else
|
||||||
if let RelishTag::Relation(_) = seg.rel {
|
{
|
||||||
} else {
|
// Add only if it exists at the requested LSN.
|
||||||
rels.insert(seg.rel);
|
if let Some(open) = &segentry.open {
|
||||||
|
if open.get_end_lsn() > lsn {
|
||||||
|
rels.insert(seg.rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if let Some((_k, _v)) = segentry
|
||||||
|
.historic
|
||||||
|
.range((Included(Lsn(0)), Included(lsn)))
|
||||||
|
.next_back()
|
||||||
|
{
|
||||||
|
rels.insert(seg.rel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(rels)
|
Ok(rels)
|
||||||
|
|||||||
Reference in New Issue
Block a user