-
Type:
Bug
-
Status: Done
-
Priority:
Medium
-
Resolution: Fixed
-
Affects Version/s: 5.6.39-83.1, 5.7.21-20
-
Fix Version/s: 5.7.21-21, 5.6.40-84.0
-
Component/s: TokuDB
-
Labels:None
The thread sanitizer detects a data race on the cache table pair attributes between the 'get and pin' method and the 'unpin' method. This race occurs when running some cache table tests. This race does not occur in the fractal tree codes use of the cache table. The cache table 'get and pin' method returns the size attribute to its caller without holding a lock. The cache table 'unpin' method updates the size attribute when holding the pair lock. This is the data race on the size attribute. The main fractal tree data path does not even use the size attribute when using the 'get and pin' method, so the race only occurs in test code.
We could either (1) lock the read of the size attribute in the 'get and pin' method, or (2) delete the size parameter from the 'get and pin' method since it is the cause of the data race and is not even necessary for its use of the cache table. This pull request deletes the size parameter from the 'get and pin' cache table method, thus removing the cause of the data race, and also simplifying the cache table API. Since some tests need access to the cache table pair size, a new method was added to provide access to this data for test purposes.
Reproduce:
Build PerconaFT/master @f27c8a781 with clang and the thread sanitizer enabled.
Run cachetable-simple-read-pin test.
155: Write of size 8 at 0x7b540000ff70 by main thread (mutexes: write M19):
155: #0 memcpy ??:? (cachetable-simple-read-pin+0x43ddb7)
155: #1 cachetable_unpin_internal(cachefile*, ctpair*, cachetable_dirty, pair_attr_s, bool) /home/rfp/projects/tokuft/ft/cachetable/cachetable.cc:1891 (libft.so+0x68747)
155: #2 toku_cachetable_unpin(cachefile*, ctpair*, cachetable_dirty, pair_attr_s) /home/rfp/projects/tokuft/ft/cachetable/cachetable.cc:1917 (libft.so+0x68593)
155: #3 toku_test_cachetable_unpin(cachefile*, blocknum_s, unsigned int, cachetable_dirty, pair_attr_s) /home/rfp/projects/tokuft/ft/cachetable/cachetable.cc:2541 (libft.so+0x6bab9)
155: #4 run_test() /home/rfp/projects/tokuft/ft/tests/cachetable-simple-read-pin.cc:136 (discriminator 2) (cachetable-simple-read-pin+0x4bab94)
155: #5 test_main(int, char const**) /home/rfp/projects/tokuft/ft/tests/cachetable-simple-read-pin.cc:187 (cachetable-simple-read-pin+0x4ba579)
155: #6 main /home/rfp/projects/tokuft/ft/tests/test.h:346 (cachetable-simple-read-pin+0x4ba445)
155:
155: Previous read of size 8 at 0x7b540000ff70 by thread T30:
155: #0 toku_cachetable_get_and_pin_with_dep_pairs(cachefile*, blocknum_s, unsigned int, void*, long, CACHETABLE_WRITE_CALLBACK, int ()(cachefile, ctpair*, int, blocknum_s, unsigned int, void*, void, pair_attr_s, int*, void*), bool ()(void, void*), int ()(void, void*, void*, int, pair_attr_s*), pair_lock_type, void*, unsigned int, ctpair*, cachetable_dirty) /home/rfp/projects/tokuft/ft/cachetable/cachetable.cc:1746 (discriminator 1) (libft.so+0x667fd)
155: #1 toku_cachetable_get_and_pin(cachefile*, blocknum_s, unsigned int, void*, long, CACHETABLE_WRITE_CALLBACK, int ()(cachefile, ctpair*, int, blocknum_s, unsigned int, void*, void, pair_attr_s, int*, void*), bool ()(void, void*), int ()(void, void*, void*, int, pair_attr_s*), bool, void*) /home/rfp/projects/tokuft/ft/cachetable/cachetable.cc:1309 (libft.so+0x65cf0)
155: #2 run_expensive_fetch(void*) /home/rfp/projects/tokuft/ft/tests/cachetable-simple-read-pin.cc:96 (discriminator 1) (cachetable-simple-read-pin+0x4bbbff)