Prometheus 源码系列:Open New DB

本文详细介绍了Prometheus数据库的初始化过程,包括创建数据目录、WAL(Write-Ahead Log)、Head的构建以及内存管理和磁盘块的加载与修剪。主要涉及的数据结构有wal.NewSize、newHead以及内存映射的chunk管理。同时,文章还阐述了如何根据最小有效时间初始化Head,并在运行时进行数据加载与修剪,确保数据的有效性和存储效率。
摘要由CSDN通过智能技术生成

prometheus 创建db

b9e4ecf383e20393fe8c9137d0d12d6c.png

  • openDBWithMetrics 参数dir 是data路径,默认是data 目录,也可在cfg.localStoragePath 指定。

    • open 调用os.MkdirAll 创建数据目录

    • open 执行walDir := filepath.Join(dir, "wal")生成wal目录

    • MigrateWAL Migrate old WAL if one exists, 暂不清楚什么情况会migrate

    • &DBdir 赋值给db,并创建db

    • wal.NewSize 创建wal,这里指定了wal目录和segmentSize,默认是*DefaultSegmentSize* = 128 * 1024 * 1024 // 128 MB。创建成功返回wlog

    • NewHead 创建head,这里传入前面生成的wlog

    • db.reload() reload reloads blocks and truncates the head and its WAL

    • db.Blocks() 获取了磁盘上的blocks,并通过blocks[len(blocks)-1].Meta().MaxTime指定了minValidTime

    • db.head.Init(minValidTime) 使用上一步的minValidTime 来初始化head

    • 最后启动db go db.run() 并返回db对象。

New Wal

3071703d67e07f0183bcd0d843ac1d8b.png

  • NewSize 传入了wal dir 和segmentSize

    • listSegments 执行具体find Segments 文件操作,并将文件名排序

    • check segmentSize%*pageSize* != 0 ,pageSize 是32kb

    • os.MkdirAll 创建wal dir

    • Segments 根据传入的wal dir 获取其中的Segments

    • writeSegmentIndex = last + 1 确定最新的SegmentIndex

    • CreateSegment(w.Dir(), writeSegmentIndex) 根据wal dir 和最新的SegmentIndex,新建segment 文件

    • w.setSegment(segment) 将segment 赋值给wal,w.donePages = int(stat.Size() / *pageSize*)初始化了当前的pageSize

New head

7d41fa509db8832304d184b45e567f9b.png

  • NewHead 传入了wal对象和HeadOptions ,HeadOptions 包含了head_chunk 的root 目录,即data目录、StripeSize 、db.chunkPool

    • mmappedChunksDir 在data目录下创建chunks_head 目录

    • openMMapFiles

    • MemPostings

    • make([]map[uint64]*memSeries, stripeSize)

    • make([]seriesHashmap, stripeSize)

    • make([]stripeLock, stripeSize)

    • newStripeSeries

    • NewUnorderedMemPostings 创建posting

    • h.minTime.Store(math.*MaxInt64*)h.maxTime.Store(math.*MinInt64*) 设置head的max、min 时间

    • NewChunkDiskMapper mmap head_chunk

db reload

eb27873f55d5ad4021682a556b1bcfa4.png

  • reload reloads blocks and truncates the head and its WAL

    • truncateMemory 首先removes old data before mint from the head,主要是head_chunk

    • truncateWAL removes old data before mint from the WAL.

    • 调用h.series.gc delete

    • h.postings.Delete delete posting

    • := h.chunkDiskMapper.Truncate(mint); Truncate the chunk m-mapper

    • initialize := h.MinTime() == math.*MaxInt64* 来判断是否是初始化的head,如果是就不用truncate

    • 调用h.gc() 进行delete

    • wal.Segments(h.wal.Dir()) 获取wal 所有文件

    • 根据要删除的index h.wal.Truncate(last + 1) 执行truncate

    • 首先通过blockDirs 加载目录

    • deletableULIDs := db.blocksToDelete(loadable)check 初加载的blocks,判断哪些block 可删除

    • 基于初加载的blocks和可删除的blocks,确认最终加载的blocks。并赋值给db.blocks db.blocks = toLoad

    • db.deleteBlocks(deletable) delete 废弃的blocks

    • 通过readMetaFile 读取元文件

    • 如果这个block 未打开,通过OpenBlock 打开该block

    • openBlocks 加载blocks目录中 blocks,主要是其meta文件

    • Truncate removes old data before mint from the head and WAL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值