mysql/stonedb-物理存储层-DPN解析
  TEZNKK3IfmPf 2023年11月12日 13 0

DPN作为PACK的元数据,对下用于访问具体的PACK,对上形成知识网格,在整个逻辑关系中,DPN的数据对于数据的访问起到了中枢的作用。

本文对DPN的数据结构的使用关系做说明。

DPN的数据成员:

uint8_t used : 1;    // occupied or not
uint8_t local : 1; // owned by a write transaction, thus to-be-commit
uint8_t synced : 1; // if the pack data in memory is up to date with the
// version on disk
uint8_t null_compressed : 1;
uint8_t data_compressed : 1;
uint8_t no_compress : 1;
uint8_t padding[3];
uint32_t base; // index of the DPN from which we copied, used by local pack
uint64_t addr; // data start address
uint64_t len; // data length
uint32_t nr; // number of records
uint32_t nn; // number of nulls
common::TX_ID xmin; // creation trx id
common::TX_ID xmax; // delete trx id
union {
int64_t min_i;
double min_d;
char min_s[8];
};
union {
int64_t max_i;
double max_d;
char max_s[8];
};
union {
int64_t sum_i;
double sum_d;
uint64_t maxlen;
};

核心成员解释:

  • addr: 指向打开的DATA文件的偏移量, 是本PACK的起始位置。 通过addr来定位在文件中的位置
  • len: PACK的长度, 用于读取PACK时
  • xmin: 在创建时的事务ID
  • xmax: 名字起做最大的事务ID,但是应当理解为本DPN指向的DPN。
  • 这种设计策略可以参考postgres的MVCC的版本控制机制
  • DPN和PACK实现了MVCC, 每个DPN中的最大的事务ID就是本DPN所指向的版本

成员-标记的PACK地址:

​​std::atomic - C++中文 - API参考文档​​

​​内存模型 - C++中文 - API参考文档​​​
 ​​std::memory_order - C++中文 - API参考文档​​

// a tagged pointer, 16 bits as ref count.
// Only read-only dpn uses it for ref counting; local dpn is managed only by
// one write session
std::atomic_ulong tagged_ptr;
uint64_t GetPackPtr() const { return tagged_ptr.load(); }
void SetPackPtr(uint64_t v) { tagged_ptr.store(v); }

语义解释:

认为是当前使用的PACK, 需要通过更多的上下文来确定逻辑

IncRef

​​std::atomic_ref<T>::compare_exchange_weak, std::atomic_ref<T>::compare_exchange_strong - C++中文 - API参考文档​​  

bool IncRef() {
auto v = tagged_ptr.load();
while (v != 0 && v != loading_flag)
if (tagged_ptr.compare_exchange_weak(v, v + tag_one)) return true;
return false;
}

RCAttr::LoadDataPackS

void RCAttr::LoadDataPackS(size_t pi, loader::ValueCache *nvs) {
auto &dpn(get_dpn(pi));

auto load_nulls = Type().NotNull() ? 0 : nvs->NumOfNulls();
auto cnt = nvs->NumOfValues();

// no need to store any values - uniform package
if (load_nulls == cnt && (dpn.nr == 0 || dpn.NullOnly())) {
dpn.nr += cnt;
dpn.nn += cnt;
return;
}

// new package or expanding so-far-null package
if (dpn.nr == 0 || dpn.NullOnly()) {
auto sp = ha_rcengine_->cache.GetOrFetchObject<Pack>(get_pc(pi), this);
dpn.SetPackPtr(reinterpret_cast<unsigned long>(sp.get()) + tag_one);
}

get_packS(pi)->LoadValues(nvs);
}

CAS

bool CAS(uint64_t &expected, uint64_t desired) { return tagged_ptr.compare_exchange_weak(expected, desired); }

std::atomic_ref<T>::compare_exchange_weak

原子地比较被引用对象的​​值表示​​​与 ​​expected​​​ 的值表示,而若它们逐位相等,则以 ​​desired​​​ 替换前者(进行读修改写操作)。否则,加载存储于被引用对象的实际值到 ​​expected​​ 中(进行加载操作)。

读修改写和加载操作的内存模型分别是 ​​success​​​ 和 ​​failure​​​ 。在 (2) 和 (4) 版本中, ​​order​​​ 同时用于读修改写操作和加载操作,除了若 order == ​​std::memory_order_acq_rel​​​ 或 order == ​​std::memory_order_release​​​ ,则分别将 ​​std::memory_order_acquire​​​ 和 ​​std::memory_order_relaxed​​ 用于加载操作。

参数

expected-到期待在 ​​atomic_ref​​ 所引用对象中找到的值的引用desired-若满足期待则要存储于被引用对象中的值success-若比较成功则用于读修改写操作的内存同步顺序。容许所有值。failure-若比较失败则用于加载操作的内存同步顺序。不能为 ​​std::memory_order_release​​ 或 ​​std::memory_order_acq_rel​​order-两个操作的内存同步顺序

返回值

若成功更改被引用数据则为 true ,否则为 false 。

注解

比较和复制是逐位的(类似 ​​std::memcmp​​​ 和 ​​std::memcpy​​ );不使用构造函数、赋值运算符或比较运算符。

允许弱形式 (1-2) 虚假地失败,即表现为 *this != expected ,即使它们相等。比较并交换在循环中时,弱版本在某些平台上将产生较好的性能。

弱比较并交换会要求循环,而强版本不会要求时,最好用强版本,除非 ​​T​​ 的对象表示可能包含陷阱位,或相同值有多种对象表示(例如浮点 NaN )。那些情况下,弱比较并交换通常能用,因为它在某些稳定的对象表示上快速收敛。

若有参与 union 某些成员,但非其他成员的值表示的位,则比较并交换可能始终失败,因为这种填充位在不参与活跃成员的值表示时拥有不确定值。

忽略决不参与对象值表示的填充位。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2024年05月31日   25   0   0 mysql
  TEZNKK3IfmPf   2024年05月17日   53   0   0 sqlmysql
  TEZNKK3IfmPf   2024年05月31日   31   0   0 数据库mysql
  TEZNKK3IfmPf   2024年05月17日   49   0   0 查询mysql索引
  TEZNKK3IfmPf   2024年05月17日   50   0   0 jsonmysql
  TEZNKK3IfmPf   2024年05月17日   49   0   0 mysqlphp
  TEZNKK3IfmPf   2024年05月31日   27   0   0 数据库mysql
TEZNKK3IfmPf