# Introduction
## 既存のHTAPシステムの課題
- [[HTAP]]向けストレージは、Multi-index, multi-storeが主流([[TiDB]]など)
- **Issue 1: Data freshness:** Multi-storeだと、まず行指向ストレージに書いて、あとから列指向ストレージにデータをコピーする。この間にタイムラグがある。これをなくすために行指向のストレージにOLAPクライアントがアクセスすることもあるが、読み取り増幅が起こる。
- **Issue 2: Sub-optimal OLTP and OLAP performance**: データの移行時にI/Oが競合し、OLTP/OLAP処理を圧迫する。
## 手法
![[Pasted image 20260430114222.png]]
- Single index, Single storeで、読み取り増幅の最小化・即時のData freshnessを達成する
- 圧縮に[[Computational Storage Drives]](CSD)を活用する
**CSDを使って書き込み増幅とページサイズのトレードオフを切り離す**
- [[B+ Tree]]の各ページを列指向にする([[Partition Attributes Across|PAX]])→ PAXを更に改良
- ページサイズを巨大にし、更にその中に4KBごとのミニページ(一つの列しか入らない)を作って、読み取り増幅を最小化している
- 書き込み増幅がひどくなりそう?と思われるが、B+ Treeの各リーフページごとにそのページ専用の小さな[[WAL]](Delta page)を割り当てる→溜まったら書き込むことで書き込み増幅を最小化している
- 全てのリーフノードに4KBのWALがあったら容量を無駄遣いするけど、[[Computational Storage Drives|CSD]]の圧縮で解決
```
【HaSiSの128KBデータページ(PAXベース)】
LBAブロック1 (4KB) = ミニページ1
[ 列Aのデータ (3KB) | ゼロ埋め (1KB) ] <-- 列Aを読みたい時はここだけフェッチ(s=1)
LBAブロック2 (4KB) = ミニページ2
[ 列Bのデータ (4KBピッタリ) ] <-- 列Bを読みたい時はここだけフェッチ(s=1)
LBAブロック3 (4KB) = ミニページ3
[ 列Cのデータ (2KB) | ゼロ埋め (2KB) ] <-- 列Cを読みたい時はここだけフェッチ(s=1)
... (これが最大128KB分続く)
```
- このゼロ埋めの部分をCSDで圧縮している
**ページ内の列読み取り増幅を削減する**
- OLAPの長い読み取りの間、OLTPのトランザクションがポンポンやってくると、その間待たざるを得ない
- Column-based Data Page + Row-based Delta Page。ページごとにデルタを管理する。OLAPはData Pageだけを読み、OLTPはDelta Pageも読む。
- しかし、ページごとに全然更新がなくてデルタが使われない...とかがあるが、[[Computational Storage Drives|CSD]]の透過圧縮で解決
# 論文
- Conference版([[USENIX]] [[FAST]]'25): [HaSiS: A Hardware-assisted Single-index Store for Hybrid Transactional and Analytical Processing](https://www.usenix.org/conference/fast25/presentation/huang)

- Journal版(ACM [[TOCS]]): [A Single-Index Store for Hybrid Transactional and Analytical Processing on Modern Computational Storage Drives](https://doi.org/10.1145/3806230)