-
Notifications
You must be signed in to change notification settings - Fork 807
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
Create index table from local table client for boltdb #2441
Conversation
7aafeb0
to
971251e
Compare
pkg/chunk/table_manager.go
Outdated
func (m *TableManager) validateClient() bool { | ||
if reflect.TypeOf(m.client).String() == "*local.tableClient" { | ||
return false | ||
} | ||
return true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this implementation is OK, will add a small test for this. Let me know if we can do it in any other better way.
1548885
to
9cee737
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @adityacs for submitting this PR. I understand this log could be quite noisy (even if it's an info, and thus could be suppressed via -log.level=warn
). Anyway, I think this is quite an hacky solution and I think we should look for a cleaner solution. I think the main problem is that the boltdb TableClient.CreateTable()
is a noop, while ListTables()
look for tables as filesystem directories. Have you check if creating the expected dir in TableClient.CreateTable()
does the job?
@pracucci Thanks for the review. Totally agree this is a hacky solution. We can create the directory in cortex/pkg/chunk/table_manager.go Line 371 in 26fa432
I haven't gone through the code flow completely. I may be wrong here. When I run the code I see that boltdb directory is created with just the last entry from the list of expected tables. So, we simply loop in here cortex/pkg/chunk/table_manager.go Line 444 in 26fa432
|
@pracucci One solution I could think of is can we change this interface to support an iterator? cortex/pkg/chunk/table_manager.go Line 444 in 26fa432
In case of boltdb we will have only one value(in case of using schema v11) to create and after creating the expected table we can return OR Somewhere we have to check if client is cortex/pkg/chunk/table_manager.go Line 371 in 26fa432
WDYT? |
I still believe this whole change should be relegated to BoltDB only. The BoltDB |
Hey @adityacs, |
@sandeepsukhani Thanks for the feedback. Will make the required changes. @pracucci Sorry for the confusion I created. I was not looking into default value set in |
e801f55
to
ce845b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a problem with keeping the file reference open while creating the files from TableManager. Suggested changes for it.
if _, err := os.OpenFile(filepath.Join(c.directory, desc.Name), os.O_RDWR|os.O_CREATE, 0666); err != nil { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would keep the file reference open. Let us do this instead.
if _, err := os.OpenFile(filepath.Join(c.directory, desc.Name), os.O_RDWR|os.O_CREATE, 0666); err != nil { | |
return err | |
} | |
return ioutil.WriteFile(filepath.Join(c.directory, desc.Name), nil, 0666) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect. Thanks @sandeepsukhani
Other way we can call Close()
on the file. However, let's stick to your code. Less number of lines 😄
@sandeepsukhani One more thing. Should we change this to cortex/pkg/chunk/table_manager.go Line 499 in 9895530
|
Are you seeing that in the logs with the change in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@sandeepsukhani Yeah, I still see in the logs |
@adityacs that sounds strange. I tried it locally and I do not see that in my logs. Can you please push the changes to see what you have? |
I am just using the default configs
|
@sandeepsukhani I have not disabled |
The throughput settings are only relevant for dynamodb, for all the other clients it is a noop so I guess you need not worry about it in this PR. I did not have any of those throughput settings set while trying it and I was not seeing that line being logged for me. Also, those throughput settings are removed from all the default configs to let only dynamodb users set them when need be. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Let us not merge this, we should have a check in |
I am checking to see if we can do it atomically. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor changes required for avoiding data loss during race condition.
@@ -36,7 +37,7 @@ func (c *TableClient) ListTables(ctx context.Context) ([]string, error) { | |||
} | |||
|
|||
func (c *TableClient) CreateTable(ctx context.Context, desc chunk.TableDesc) error { | |||
return nil | |||
return ioutil.WriteFile(filepath.Join(c.directory, desc.Name), nil, 0666) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @adityacs for all the back and forth. To avoid any data loss during race conditions let us change it to the following which should create the file if it does not exist and if it is there already, it should open the file in read-only mode.
return ioutil.WriteFile(filepath.Join(c.directory, desc.Name), nil, 0666) | |
fl, err := os.OpenFile(filepath.Join(c.directory, desc.Name), os.O_CREATE|os.O_RDONLY, 0666) | |
if err != nil { | |
return err | |
} | |
return fl.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandeepsukhani Just one question before making this change.
Since, we don't write any data while we create file using ioutil.Writefile
and ioutil.Writefile
opens the file in WRONLY
mode and also we have the bbolt.Open()
in boltdb_index_client
which in turn does a file lock when doing any Read/Write operation https://github.com/etcd-io/bbolt/blob/a8af23b57f672fef05637de531bba5aa00013364/db.go#L223
Would there be data race still?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think only way to tell about it for sure is to write some tests with that scenario. If we get an error here when file is already locked then we can avoid returning an error for it because it means file is already there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Will try to add the tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandeepsukhani You will be definitely aware of this. Still, this is what I found out.
We could have not used ioutil.Writefile
since it truncates the file if already existing.
Also, regarding boltdb file lock. It only does the advisory
lock so any other process can be non cooperative and override the lock. I don't think we would run in to that situation here as the binary runs as single process. So, adding test for it is not required.
So, we are good with the recent change you mentioned. Have added a test to verify "trying to create an already existing file doesn't modify any content". This is not so much required to test. We can remove it.
Signed-off-by: Aditya C S <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I have a feeling that os.OpenFile
does not honor/check file locks. Since we are opening the file in readonly mode it still is safe for us, without acquiring a lock. I think this is good to go.
@sandeepsukhani Yeah |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
What this PR does:
When using boltdb for index, calling create and update table doesn't have any action and this makes logs too much verbose.
Reference: grafana/loki#1786
Checklist