Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在window下 Merge报错 #578

Open
barryzxy opened this issue Jan 10, 2024 · 3 comments
Open

在window下 Merge报错 #578

barryzxy opened this issue Jan 10, 2024 · 3 comments
Assignees

Comments

@barryzxy
Copy link

Describe the bug
在windows下,Merge的时候,程序执行中,本次生成的.dat文件merge时,删除不了,如果重启,之前生成的.dat可以删,当是本次程序生成的还是删除不了

To Reproduce
Steps to reproduce the behavior(Be specific!):

  1. 先写入大量数据,
  2. 以相同的key重复写入之前的数据,
  3. 同步merge,发现merge后没有删除文件

Give sample code if you can.

func main() {
	fmt.Println(time.Now())
	options := nutsdb.DefaultOptions
	options.SegmentSize = 1 * 1024 * 1024
	db, err := nutsdb.Open(
		options,
		nutsdb.WithDir("./nutsdb"),
	)
	if err != nil {
		log.Fatal(err)
	}
	if err := db.Update(
		func(tx *nutsdb.Tx) error {
			return tx.NewBucket(nutsdb.DataStructureBTree, "bucket")
		},
	); err != nil {
		// log.Fatal(err)
	}
	defer db.Close()
	fmt.Println(time.Now())
	{
		err := db.Merge()
		fmt.Println("Merge", err)
	}
	fmt.Println(time.Now())
	datax := [512]byte{}
	for i := 0; i < 512; i++ {
		datax[i] = byte(i)
	}
	for i := 0; i < 10*1000; i++ {
		err := db.Update(
			func(tx *nutsdb.Tx) error {
				return tx.Put("bucket", []byte("key"+strconv.Itoa(i)), datax[:], 0)
			},
		)
		if err != nil {
			fmt.Println(err)
		}
		if i%1000 == 0 {
			fmt.Println(i)
			time.Sleep(time.Duration(1) * time.Microsecond)
			err := db.Merge()
			fmt.Println("Merge", err)
		}
	}
	
	for i := 0; i < 10*1000; i++ {
		err := db.Update(
			func(tx *nutsdb.Tx) error {
				return tx.Put("bucket", []byte("key"+strconv.Itoa(i)), datax[:], 0)
			},
		)
		if err != nil {
			fmt.Println(err)
		}
		if i%1000 == 0 {
			fmt.Println(i)
			time.Sleep(time.Duration(1) * time.Microsecond)
			err := db.Merge()
			fmt.Println("Merge", err)
		}
	}
	
}

Expected behavior
meger后应该删除之前的.dat,释放硬盘空间
What actually happens
A clear and concise description of what actually happens.

Screenshots

37fda13d7228ae4c777f5110a5d771d

please complete the following information :

  • OS: windows11
  • NutsDB Version:1.0.3

Additional context
Add any other context about the problem here.

@TremblingV5
Copy link
Contributor

Windows 10 稳定复现。暂时没有测试其他版本。
Ubuntu 22.04 稳定不复现。

这个报错很多时候会出现在os.OpenFile打开文件后,没有调用Close函数就直接调用了os.Remove的场景

代码中看起来有按时释放db.ActiveFile,由于Ubuntu是能正常执行完代码的,所以怀疑是在Windows系统下,没能正确释放对已有文件的占用,所以在删除时会报这个错,后续我看在Mac上能不能复现(估计不能)

这个问题我可能会在这周末再在Windows上尝试下,手头这台windows有点太卡了 QAQ
后续可能需要调查下有没有把文件正常释放掉,以及在Ubuntu和Windows上释放文件占用的区别

@TremblingV5
Copy link
Contributor

@barryzxy

这个问题的原因已确定,问题在于nutsdbgetFd函数中会对传入的路径参数调用filepath.Clean(),该函数会将传入的路径转化为一个“标准路径”,例如会将E://nutsdb转化为E:\\nutsdb。由于这个路径的不同,导致nutsdb在Windows下不能正常的释放文件。

建议可以先work around一下,即使用如下代码打开一个db:

db, err := nutsdb.Open(
    options,
    nutsdb.WithDir(filepath.Clean("./nutsdb")),
)

这样,确保在传入时就使用了一个“标准路径”

@bigboss2063
Copy link
Member

我们应该可以内部处理一下这个路径?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants