MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
table_cache-t.cc
1 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 // First include (the generated) my_config.h, to get correct platform defines.
17 #include "my_config.h"
18 #include <gtest/gtest.h>
19 #include "test_utils.h"
20 
21 #include "table_cache.h"
22 
23 #include "ha_example.h"
24 
25 /*
26  We need example_hton to be able short-cut creation of example
27  handler instances for mock TABLE objects.
28 */
29 extern handlerton *example_hton;
30 
31 namespace table_cache_unittest {
32 
34 
35 
45 class TableCacheBasicTest : public ::testing::Test
46 {
47 protected:
48  static const uint MAX_THREADS= 3;
49 
50  virtual void SetUp()
51  {
52  for (uint i= 0; i < MAX_THREADS; ++i)
53  {
54  initializer[i].SetUp();
55  initializer[i].thd()->thread_id= i + 1;
56  }
57 
58  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
59  }
60  virtual void TearDown()
61  {
62  for (uint i= 0; i < MAX_THREADS; ++i)
63  initializer[i].TearDown();
64  }
65 
66  THD *get_thd(uint index) { return initializer[index].thd(); }
67 
68  Server_initializer initializer[MAX_THREADS];
69 };
70 
71 
78 {
79 protected:
80  virtual uint CachesNumber() { return 1; }
81  virtual void SetUp()
82  {
83  TableCacheBasicTest::SetUp();
84 
85  /*
86  In addition to table_cache_manager we want to have initialized
87  TDC so we can use its HASH object for calculating hash values
88  and be able to free TABLE objects correctly (we need LOCK_open
89  initialized for this).
90  */
91  table_cache_instances= CachesNumber();
92  table_cache_size_per_instance= 100;
93  ASSERT_FALSE(table_def_init());
94  }
95  virtual void TearDown()
96  {
97  table_def_free();
98  TableCacheBasicTest::TearDown();
99  }
100 };
101 
102 
109 {
110 protected:
111  virtual uint CachesNumber() { return 2; }
112 };
113 
114 
120 class Mock_share : public TABLE_SHARE
121 {
122  MEM_ROOT m_mem_root;
124 
125 public:
126  Mock_share(const char *key)
127  {
128  memset((TABLE_SHARE *)this, 0, sizeof(TABLE_SHARE));
129  /*
130  Both table_cache_key and cache_element array are used by
131  Table_cache code.
132  */
133  table_cache_key.str= (char*)key;
134  table_cache_key.length= strlen(key);
135  memset(cache_element_arr, 0, sizeof(cache_element_arr));
136  cache_element= cache_element_arr;
137  // MEM_ROOT is used for constructing ha_example() instances.
138  init_alloc_root(&m_mem_root, 1024, 0);
139  /*
140  Assertion in some of Table_cache methods check that version of
141  the share is up-to-date.
142  */
143  version= refresh_version;
144  // Ensure that share is never destroyed.
145  ref_count= UINT_MAX;
146  }
147 
148  ~Mock_share()
149  {
150  free_root(&m_mem_root, MYF(0));
151  }
152 
153  TABLE *create_table(THD *thd)
154  {
155  TABLE *result= (TABLE *)my_malloc(sizeof(TABLE), MYF(0));
156 
157  memset(result, 0, sizeof(TABLE));
158  result->s= this;
159  // We create TABLE which is already marked as used
160  result->in_use= thd;
161  /*
162  Assertions in some of Table_cache methods need non-NULL
163  TABLE::file and TABLE::db_stat. Code that frees unused
164  TABLE objects needs proper "handler" instance.
165  */
166  result->file= new (&m_mem_root) ha_example(example_hton, this);
167  result->db_stat= HA_READ_ONLY;
168 
169  return result;
170  }
171 
172  void destroy_table(TABLE *table)
173  {
174  my_free(table);
175  }
176 };
177 
178 // Google Test recommends DeathTest suffix for classes used in death tests.
181 
182 /*
183  Test initilization/destruction of Table_cache.
184 */
185 
186 TEST_F(TableCacheBasicDeathTest, CacheCreateAndDestroy)
187 {
188  Table_cache table_cache;
189 
190  ASSERT_FALSE(table_cache.init());
191 
192  // Cache should be empty after creation
193  EXPECT_EQ(0U, table_cache.cached_tables());
194 
195  // Cache should be not locked after creation
196 #ifdef SAFE_MUTEX
197  EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
198  ".*Assertion.*count > 0.*pthread_equal.*");
199 #endif
200  table_cache.destroy();
201 }
202 
203 
204 /*
205  Test locking for Table_cache object.
206 */
207 
208 TEST_F(TableCacheBasicDeathTest, CacheLockAndUnlock)
209 {
210  Table_cache table_cache;
211 
212  ASSERT_FALSE(table_cache.init());
213 
214 #ifdef SAFE_MUTEX
215  // Cache should not be locked after creation
216  EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
217  ".*Assertion.*count > 0.*pthread_equal.*");
218 #endif
219 
220  // And get locked after we call its lock() method
221  table_cache.lock();
222  table_cache.assert_owner();
223 
224  // And get unlocked after we call its unlock() method
225  table_cache.unlock();
226 #ifdef SAFE_MUTEX
227  EXPECT_DEATH_IF_SUPPORTED(table_cache.assert_owner(),
228  ".*Assertion.*count > 0.*pthread_equal.*");
229 #endif
230 
231  table_cache.destroy();
232 }
233 
234 
235 /*
236  Tests for the rest of methods of Table_cache need to use an
237  object controlled by the global instance of Table_cache_manager.
238  Let us start testing of Table_cache_manager with test for
239  its initialization/destruction. This test also covers well
240  Table_cache_manager::get_cache() method.
241 */
242 
243 TEST_F(TableCacheBasicDeathTest, ManagerCreateAndDestroy)
244 {
245  // Request two instances of Table_cache
246  table_cache_instances= 2;
247 
248  ASSERT_FALSE(table_cache_manager.init());
249 
250  // All caches are empty after creation
251  EXPECT_EQ(0U, table_cache_manager.cached_tables());
252 
253  // There should be two different caches in the manager
254  Table_cache *cache_1, *cache_2, *cache_3;
255  cache_1= table_cache_manager.get_cache(get_thd(0));
256  cache_2= table_cache_manager.get_cache(get_thd(1));
257  cache_3= table_cache_manager.get_cache(get_thd(2));
258  EXPECT_TRUE(cache_1 != cache_2);
259  // And not three !
260  EXPECT_TRUE(cache_3 == cache_1);
261 
262  // Both caches should be empty
263  EXPECT_EQ(0U, cache_1->cached_tables());
264  EXPECT_EQ(0U, cache_2->cached_tables());
265 
266  // And not locked
267 #ifdef SAFE_MUTEX
268  EXPECT_DEATH_IF_SUPPORTED(cache_1->assert_owner(),
269  ".*Assertion.*count > 0.*pthread_equal.*");
270  EXPECT_DEATH_IF_SUPPORTED(cache_2->assert_owner(),
271  ".*Assertion.*count > 0.*pthread_equal.*");
272 #endif
273 
274  table_cache_manager.destroy();
275 }
276 
277 
278 /*
279  Test addition and removal of TABLE objects to/from the table cache.
280 */
281 
282 TEST_F(TableCacheSingleCacheTest, CacheAddAndRemove)
283 {
284  THD *thd= get_thd(0);
285 
286  Mock_share share_1("share_1");
287  TABLE *table_1= share_1.create_table(thd);
288 
289  Table_cache *table_cache= table_cache_manager.get_cache(thd);
290  table_cache->lock();
291  EXPECT_FALSE(table_cache->add_used_table(thd, table_1));
292 
293  // There should be one TABLE in the cache after we have added table_1.
294  EXPECT_EQ(1U, table_cache->cached_tables());
295 
296  // There should be no unused TABLE objects for the same table in the
297  // cache. OTOH it should contain info about table share of table_1.
298  my_hash_value_type hash_value= my_calc_hash(&table_def_cache,
299  (uchar*)share_1.table_cache_key.str,
300  share_1.table_cache_key.length);
301  TABLE *table_2;
302  TABLE_SHARE *share_2;
303  table_2= table_cache->get_table(thd, hash_value,
304  share_1.table_cache_key.str,
305  share_1.table_cache_key.length,
306  &share_2);
307  EXPECT_TRUE(table_2 == NULL);
308  EXPECT_TRUE(share_2 == &share_1);
309 
310  // Table_cache_iterator should be able to find only one TABLE instance
311  // in all caches. And this instance should be table_1.
312  Table_cache_iterator it(&share_1);
313  EXPECT_TRUE(it++ == table_1);
314  EXPECT_TRUE(it++ == NULL);
315 
316  // We must be able to release TABLE into table cache and reuse it after
317  // this.
318  table_cache->release_table(thd, table_1);
319  table_2= table_cache->get_table(thd, hash_value,
320  share_1.table_cache_key.str,
321  share_1.table_cache_key.length,
322  &share_2);
323  EXPECT_TRUE(table_2 == table_1);
324  EXPECT_TRUE(share_2 == &share_1);
325 
326  table_cache->remove_table(table_1);
327 
328  // Once TABLE is removed from the cache the latter should become empty.
329  EXPECT_EQ(0U, table_cache->cached_tables());
330 
331  table_2= table_cache->get_table(thd, hash_value,
332  share_1.table_cache_key.str,
333  share_1.table_cache_key.length,
334  &share_2);
335  EXPECT_TRUE(table_2 == NULL);
336  EXPECT_TRUE(share_2 == NULL);
337 
338  it.rewind();
339  EXPECT_TRUE(it++ == NULL);
340 
341  // Also it should be possible to remove unused TABLE from the cache
342  // Add TABLE instance and mark it as unused
343  EXPECT_FALSE(table_cache->add_used_table(thd, table_1));
344  table_cache->release_table(thd, table_1);
345 
346  table_cache->remove_table(table_1);
347 
348  // Once TABLE is removed from cache the latter should become empty.
349  EXPECT_EQ(0U, table_cache->cached_tables());
350 
351  table_2= table_cache->get_table(thd, hash_value,
352  share_1.table_cache_key.str,
353  share_1.table_cache_key.length,
354  &share_2);
355  EXPECT_TRUE(table_2 == NULL);
356  EXPECT_TRUE(share_2 == NULL);
357 
358  table_cache->unlock();
359 
360  share_1.destroy_table(table_1);
361 }
362 
363 
364 /*
365  Now let us test how Table_cache handles overflows.
366 */
367 
368 TEST_F(TableCacheSingleCacheTest, CacheOverflow)
369 {
370  THD *thd= get_thd(0);
371 
372  // Set cache size low so it will overflow quickly.
373  table_cache_size_per_instance= 2;
374 
375  Mock_share share_1("share_1");
376  Mock_share share_2("share_2");
377  TABLE *table_1= share_1.create_table(thd);
378  TABLE *table_2= share_1.create_table(thd);
379  TABLE *table_3= share_2.create_table(thd);
380 
381  Table_cache *table_cache= table_cache_manager.get_cache(thd);
382 
383  table_cache->lock();
384  table_cache->add_used_table(thd, table_1);
385  table_cache->add_used_table(thd, table_2);
386 
387  // There should be two TABLE instances in the cache.
388  EXPECT_EQ(2U, table_cache->cached_tables());
389 
390  table_cache->release_table(thd, table_1);
391  table_cache->release_table(thd, table_2);
392 
393  // Still there should be two TABLE instances in the cache.
394  EXPECT_EQ(2U, table_cache->cached_tables());
395 
396  table_cache->add_used_table(thd, table_3);
397 
398  // One TABLE was added and one expelled (table_1), so still two TABLE objects.
399  EXPECT_EQ(2U, table_cache->cached_tables());
400 
401  // Old value of table_1 points to garbage thanks to expelling
402  table_1= share_1.create_table(thd);
403  table_cache->add_used_table(thd, table_1);
404 
405  // Still two TABLE instances (table_2 was expelled).
406  EXPECT_EQ(2U, table_cache->cached_tables());
407 
408  // Old value of table_2 points to garbage thanks to expelling
409  table_2= share_1.create_table(thd);
410  table_cache->add_used_table(thd, table_2);
411 
412  /*
413  Now we should have three TABLE instances in cache since all
414  of them are used.
415  */
416  EXPECT_EQ(3U, table_cache->cached_tables());
417 
418  table_cache->release_table(thd, table_2);
419 
420  // The first table that gets released is expelled.
421  EXPECT_EQ(2U, table_cache->cached_tables());
422 
423  table_cache->remove_table(table_1);
424  table_cache->remove_table(table_3);
425 
426  // Cache should be empty after that
427  EXPECT_EQ(0U, table_cache->cached_tables());
428 
429  table_cache->unlock();
430 
431  share_1.destroy_table(table_1);
432  share_1.destroy_table(table_3);
433 }
434 
435 
436 TEST_F(TableCacheSingleCacheTest, CacheGetAndRelease)
437 {
438  THD *thd= get_thd(0);
439 
440  Table_cache *table_cache= table_cache_manager.get_cache(thd);
441 
442  table_cache->lock();
443 
444  TABLE *table_1, *table_2, *table_3;
445  Mock_share share_1("share_1"), share_0("share_0");
446  TABLE_SHARE *share_2;
447 
448  // There should be no TABLE in cache, nor information about share.
449  my_hash_value_type hash_value_1= my_calc_hash(&table_def_cache,
450  (uchar*)share_1.table_cache_key.str,
451  share_1.table_cache_key.length);
452  table_1= table_cache->get_table(thd, hash_value_1,
453  share_1.table_cache_key.str,
454  share_1.table_cache_key.length,
455  &share_2);
456  EXPECT_TRUE(table_1 == NULL);
457  EXPECT_TRUE(share_2 == NULL);
458 
459  table_1= share_1.create_table(thd);
460  table_cache->add_used_table(thd, table_1);
461 
462  // There should be no unused TABLE in cache, but there should be
463  // information about the share.
464  table_2= table_cache->get_table(thd, hash_value_1,
465  share_1.table_cache_key.str,
466  share_1.table_cache_key.length,
467  &share_2);
468  EXPECT_TRUE(table_2 == NULL);
469  EXPECT_TRUE(share_2 == &share_1);
470 
471  // There should be even no information about the share for which
472  // TABLE was not added to cache.
473  my_hash_value_type hash_value_0= my_calc_hash(&table_def_cache,
474  (uchar*)share_0.table_cache_key.str,
475  share_0.table_cache_key.length);
476  table_2= table_cache->get_table(thd, hash_value_0,
477  share_0.table_cache_key.str,
478  share_0.table_cache_key.length,
479  &share_2);
480  EXPECT_TRUE(table_2 == NULL);
481  EXPECT_TRUE(share_2 == NULL);
482 
483  table_2= share_1.create_table(thd);
484  table_cache->add_used_table(thd, table_2);
485 
486  // Still there should be no unused TABLE in cache, but there should
487  // be information about the share.
488  table_3= table_cache->get_table(thd, hash_value_1,
489  share_1.table_cache_key.str,
490  share_1.table_cache_key.length,
491  &share_2);
492  EXPECT_TRUE(table_3 == NULL);
493  EXPECT_TRUE(share_2 == &share_1);
494 
495  table_cache->release_table(thd, table_1);
496 
497  // After releasing one of TABLE objects it should be possible to get
498  // unused TABLE from cache.
499  table_3= table_cache->get_table(thd, hash_value_1,
500  share_1.table_cache_key.str,
501  share_1.table_cache_key.length,
502  &share_2);
503  EXPECT_TRUE(table_3 == table_1);
504  EXPECT_TRUE(share_2 == &share_1);
505 
506  // But only once!
507  table_3= table_cache->get_table(thd, hash_value_1,
508  share_1.table_cache_key.str,
509  share_1.table_cache_key.length,
510  &share_2);
511  EXPECT_TRUE(table_3 == NULL);
512  EXPECT_TRUE(share_2 == &share_1);
513 
514  // After releasing of both TABLE objects it should be possible to
515  // get two unused TABLE objects from cache (for 'share_1').
516  // There should be nothing for 'share_0'.
517  table_cache->release_table(thd, table_1);
518  table_cache->release_table(thd, table_2);
519 
520  table_3= table_cache->get_table(thd, hash_value_0,
521  share_0.table_cache_key.str,
522  share_0.table_cache_key.length,
523  &share_2);
524  EXPECT_TRUE(table_3 == NULL);
525  EXPECT_TRUE(share_2 == NULL);
526 
527 
528  table_3= table_cache->get_table(thd, hash_value_1,
529  share_1.table_cache_key.str,
530  share_1.table_cache_key.length,
531  &share_2);
532  EXPECT_TRUE(table_3 != NULL);
533  EXPECT_TRUE(share_2 == &share_1);
534  table_3= table_cache->get_table(thd, hash_value_1,
535  share_1.table_cache_key.str,
536  share_1.table_cache_key.length,
537  &share_2);
538  EXPECT_TRUE(table_3 != NULL);
539  EXPECT_TRUE(share_2 == &share_1);
540  table_3= table_cache->get_table(thd, hash_value_1,
541  share_1.table_cache_key.str,
542  share_1.table_cache_key.length,
543  &share_2);
544  EXPECT_TRUE(table_3 == NULL);
545  EXPECT_TRUE(share_2 == &share_1);
546 
547  // Clean-up
548  table_cache->remove_table(table_1);
549  table_cache->remove_table(table_2);
550 
551  share_1.destroy_table(table_1);
552  share_1.destroy_table(table_2);
553 
554  table_cache->unlock();
555 }
556 
557 
558 /*
559  Test for Table_cache_manager/Table_cache::free_all_unused_tables().
560 */
561 
562 TEST_F(TableCacheDoubleCacheTest, ManagerFreeAllUnused)
563 {
564  THD *thd_1= get_thd(0);
565  THD *thd_2= get_thd(1);
566 
567  Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
568  Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
569 
570  // There should be no TABLE instances in all cachea.
571  EXPECT_EQ(0U, table_cache_manager.cached_tables());
572 
573  Mock_share share_1("share_1");
574  Mock_share share_2("share_2");
575  Mock_share share_3("share_2");
576  TABLE *table_1= share_1.create_table(thd_1);
577  TABLE *table_2= share_1.create_table(thd_1);
578  TABLE *table_3= share_2.create_table(thd_1);
579  TABLE *table_4= share_2.create_table(thd_1);
580  TABLE *table_5= share_1.create_table(thd_2);
581  TABLE *table_6= share_3.create_table(thd_2);
582 
583  table_cache_manager.lock_all_and_tdc();
584 
585  table_cache_1->add_used_table(thd_1, table_1);
586  table_cache_1->add_used_table(thd_1, table_2);
587  table_cache_1->add_used_table(thd_1, table_3);
588  table_cache_1->add_used_table(thd_1, table_4);
589  table_cache_2->add_used_table(thd_2, table_5);
590  table_cache_2->add_used_table(thd_2, table_6);
591 
592  EXPECT_EQ(4U, table_cache_1->cached_tables());
593  EXPECT_EQ(2U, table_cache_2->cached_tables());
594  EXPECT_EQ(6U, table_cache_manager.cached_tables());
595 
596  table_cache_manager.free_all_unused_tables();
597 
598  // All TABLE instances should stay around in caches as
599  // all of them are used.
600  EXPECT_EQ(4U, table_cache_1->cached_tables());
601  EXPECT_EQ(2U, table_cache_2->cached_tables());
602  EXPECT_EQ(6U, table_cache_manager.cached_tables());
603 
604  table_cache_1->release_table(thd_1, table_1);
605 
606  table_cache_manager.free_all_unused_tables();
607 
608  // One table should be freed. So there should be 3 + 2 TABLE instances.
609  EXPECT_EQ(3U, table_cache_1->cached_tables());
610  EXPECT_EQ(2U, table_cache_2->cached_tables());
611  EXPECT_EQ(5U, table_cache_manager.cached_tables());
612 
613  table_cache_1->release_table(thd_1, table_2);
614  table_cache_1->release_table(thd_1, table_3);
615  table_cache_2->release_table(thd_2, table_5);
616 
617  table_cache_manager.free_all_unused_tables();
618 
619  // Now there should be 1 + 1 used TABLE instances left.
620  EXPECT_EQ(1U, table_cache_1->cached_tables());
621  EXPECT_EQ(1U, table_cache_2->cached_tables());
622  EXPECT_EQ(2U, table_cache_manager.cached_tables());
623 
624  table_cache_1->release_table(thd_1, table_4);
625 
626  table_cache_manager.free_all_unused_tables();
627 
628  // There should be 0 + 1 TABLE instances around.
629  EXPECT_EQ(0U, table_cache_1->cached_tables());
630  EXPECT_EQ(1U, table_cache_2->cached_tables());
631  EXPECT_EQ(1U, table_cache_manager.cached_tables());
632 
633  table_cache_2->release_table(thd_2, table_6);
634 
635  table_cache_manager.free_all_unused_tables();
636 
637  // All caches should become empty.
638  EXPECT_EQ(0U, table_cache_1->cached_tables());
639  EXPECT_EQ(0U, table_cache_2->cached_tables());
640  EXPECT_EQ(0U, table_cache_manager.cached_tables());
641 
642  table_cache_manager.unlock_all_and_tdc();
643 }
644 
645 
646 /*
647  Test for Table_cache_manager/Table_cache::cached_tables().
648 */
649 
650 TEST_F(TableCacheDoubleCacheTest, ManagerCachedTables)
651 {
652  THD *thd_1= get_thd(0);
653  THD *thd_2= get_thd(1);
654 
655  Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
656  Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
657 
658  // There should be no TABLE instances in all cachea.
659  EXPECT_EQ(0U, table_cache_1->cached_tables());
660  EXPECT_EQ(0U, table_cache_2->cached_tables());
661  EXPECT_EQ(0U, table_cache_manager.cached_tables());
662 
663  Mock_share share_1("share_1");
664  Mock_share share_2("share_2");
665  TABLE *table_1= share_1.create_table(thd_1);
666  TABLE *table_2= share_1.create_table(thd_1);
667  TABLE *table_3= share_2.create_table(thd_1);
668  TABLE *table_4= share_1.create_table(thd_2);
669  TABLE *table_5= share_2.create_table(thd_2);
670 
671  table_cache_manager.lock_all_and_tdc();
672 
673  table_cache_1->add_used_table(thd_1, table_1);
674  table_cache_1->add_used_table(thd_1, table_2);
675  table_cache_1->add_used_table(thd_1, table_3);
676 
677  // There should be 3 + 0 TABLE objects in cache
678  EXPECT_EQ(3U, table_cache_1->cached_tables());
679  EXPECT_EQ(0U, table_cache_2->cached_tables());
680  EXPECT_EQ(3U, table_cache_manager.cached_tables());
681 
682  table_cache_2->add_used_table(thd_2, table_4);
683  table_cache_2->add_used_table(thd_2, table_5);
684 
685  // There should be 3 + 2 TABLE objects in cache
686  EXPECT_EQ(3U, table_cache_1->cached_tables());
687  EXPECT_EQ(2U, table_cache_2->cached_tables());
688  EXPECT_EQ(5U, table_cache_manager.cached_tables());
689 
690  table_cache_1->release_table(thd_1, table_1);
691  table_cache_2->release_table(thd_2, table_4);
692 
693  // There should be the same number of TABLE objects - 3 + 2
694  EXPECT_EQ(3U, table_cache_1->cached_tables());
695  EXPECT_EQ(2U, table_cache_2->cached_tables());
696  EXPECT_EQ(5U, table_cache_manager.cached_tables());
697 
698  table_cache_2->remove_table(table_5);
699 
700  // There should be 3 + 1 TABLE objects in cache
701  EXPECT_EQ(3U, table_cache_1->cached_tables());
702  EXPECT_EQ(1U, table_cache_2->cached_tables());
703  EXPECT_EQ(4U, table_cache_manager.cached_tables());
704 
705  table_cache_1->remove_table(table_1);
706  table_cache_2->remove_table(table_4);
707 
708  // There should be 2 + 0 TABLE objects in cache
709  EXPECT_EQ(2U, table_cache_1->cached_tables());
710  EXPECT_EQ(0U, table_cache_2->cached_tables());
711  EXPECT_EQ(2U, table_cache_manager.cached_tables());
712 
713  table_cache_1->remove_table(table_2);
714  table_cache_1->remove_table(table_3);
715 
716  // Caches should be empty
717  EXPECT_EQ(0U, table_cache_1->cached_tables());
718  EXPECT_EQ(0U, table_cache_2->cached_tables());
719  EXPECT_EQ(0U, table_cache_manager.cached_tables());
720 
721  table_cache_manager.unlock_all_and_tdc();
722 
723  share_1.destroy_table(table_1);
724  share_1.destroy_table(table_2);
725  share_2.destroy_table(table_3);
726  share_1.destroy_table(table_4);
727  share_2.destroy_table(table_5);
728 }
729 
730 
731 /*
732  Coverage for lock and unlock methods of Table_cache_manager class.
733 */
734 
735 TEST_F(TableCacheDoubleCacheDeathTest, ManagerLockAndUnlock)
736 {
737  // Nor caches nor LOCK_open should not be locked after initialization
738 #ifdef SAFE_MUTEX
739  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all(),
740  ".*Assertion.*count > 0.*pthread_equal.*");
741  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all_and_tdc(),
742  ".*Assertion.*count > 0.*pthread_equal.*");
743 #endif
744 
745  // And get locked after we call its lock_all_and_tdc() method.
746  table_cache_manager.lock_all_and_tdc();
747  table_cache_manager.assert_owner_all();
748  table_cache_manager.assert_owner_all_and_tdc();
749 
750  // In addition to Table_cache_manager method we check this by
751  // calling Table_cache methods and asserting state of LOCK_open.
752  Table_cache *cache_1= table_cache_manager.get_cache(get_thd(0));
753  Table_cache *cache_2= table_cache_manager.get_cache(get_thd(1));
754 
755  cache_1->assert_owner();
756  cache_2->assert_owner();
758 
759  // Locks should be unlocked after we call unlock method
760  table_cache_manager.unlock_all_and_tdc();
761 
762 #ifdef SAFE_MUTEX
763  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all(),
764  ".*Assertion.*count > 0.*pthread_equal.*");
765  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.assert_owner_all_and_tdc(),
766  ".*Assertion.*count > 0.*pthread_equal.*");
767 #endif
768 }
769 
770 
771 /*
772  Coverage for Table_cache_manager::free_table();
773 */
774 
775 TEST_F(TableCacheDoubleCacheDeathTest, ManagerFreeTable)
776 {
777  THD *thd_1= get_thd(0);
778  THD *thd_2= get_thd(1);
779 
780  Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
781  Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
782 
783  Mock_share share_1("share_1");
784  Mock_share share_2("share_2");
785  TABLE *table_1= share_1.create_table(thd_1);
786  TABLE *table_2= share_1.create_table(thd_1);
787  TABLE *table_3= share_2.create_table(thd_1);
788  TABLE *table_4= share_1.create_table(thd_2);
789  TABLE *table_5= share_2.create_table(thd_2);
790 
791  table_cache_manager.lock_all_and_tdc();
792 
793  /*
794  Coverage for TDC_RT_REMOVE_ALL case.
795  */
796  table_cache_1->add_used_table(thd_1, table_1);
797  table_cache_1->add_used_table(thd_1, table_2);
798  table_cache_1->release_table(thd_1, table_2);
799  table_cache_1->add_used_table(thd_1, table_3);
800  table_cache_2->add_used_table(thd_2, table_4);
801  table_cache_2->add_used_table(thd_2, table_5);
802 
803  EXPECT_EQ(5U, table_cache_manager.cached_tables());
804 
805  // There should be assert failure since we are trying
806  // to free all tables for share_1, while some tables
807  // are in use.
808 #ifndef DBUG_OFF
809  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.free_table(thd_1,
810  TDC_RT_REMOVE_ALL,
811  &share_1),
812  ".*Assertion.*is_empty.*");
813 #endif
814 
815  table_cache_1->release_table(thd_1, table_1);
816  table_cache_2->release_table(thd_2, table_4);
817 
818  // After all tables for share_1 marked as unused freeing
819  // all tables should succeed.
820  table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_ALL, &share_1);
821 
822  // We still should have 2 TABLE objects for share_2.
823  EXPECT_EQ(2U, table_cache_manager.cached_tables());
824 
825  /*
826  Coverage for TDC_RT_REMOVE_NOT_OWN case.
827  */
828  table_1= share_1.create_table(thd_1);
829  table_2= share_1.create_table(thd_1);
830  table_4= share_1.create_table(thd_2);
831 
832  table_cache_1->add_used_table(thd_1, table_1);
833  table_cache_1->add_used_table(thd_1, table_2);
834  table_cache_1->release_table(thd_1, table_2);
835  table_cache_2->add_used_table(thd_2, table_4);
836 
837  EXPECT_EQ(5U, table_cache_manager.cached_tables());
838 
839  // There should be assert failure since we are trying
840  // to free all not own TABLEs for share_1, while thd_2
841  // has a TABLE object for it in used
842 #ifndef DBUG_OFF
843  EXPECT_DEATH_IF_SUPPORTED(table_cache_manager.free_table(thd_1,
844  TDC_RT_REMOVE_NOT_OWN,
845  &share_1),
846  ".*Assertion.*0.*");
847 #endif
848 
849  table_cache_2->release_table(thd_2, table_4);
850 
851  // After TABLE owned by thd_2 is marked as unused, the below
852  // call should succeed.
853  table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_NOT_OWN, &share_1);
854 
855  // We still have 1 TABLE object for share_1 in thd_1 and
856  // 2 TABLE objects for share_2.
857  EXPECT_EQ(3U, table_cache_manager.cached_tables());
858 
859  /*
860  Coverage for TDC_RT_REMOVE_UNUSED case.
861  */
862  table_2= share_1.create_table(thd_1);
863  table_4= share_1.create_table(thd_2);
864 
865  table_cache_1->add_used_table(thd_1, table_2);
866  table_cache_1->release_table(thd_1, table_2);
867  table_cache_2->add_used_table(thd_2, table_4);
868 
869  EXPECT_EQ(5U, table_cache_manager.cached_tables());
870 
871  table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_UNUSED, &share_1);
872 
873  // The above call should have been freed only 1 table.
874  EXPECT_EQ(4U, table_cache_manager.cached_tables());
875 
876  // Mark all remaining TABLE objects for share_1 as unused
877  table_cache_1->release_table(thd_1, table_1);
878  table_cache_2->release_table(thd_2, table_4);
879 
880  table_cache_manager.free_table(thd_1, TDC_RT_REMOVE_UNUSED, &share_1);
881 
882  // The above call should free all unused TABLE objects for share_1.
883  // Therefore only 2 objects for share_2 should be remaining
884  EXPECT_EQ(2U, table_cache_manager.cached_tables());
885 
886  // Clean-up.
887  table_cache_1->remove_table(table_3);
888  table_cache_2->remove_table(table_5);
889 
890  share_2.destroy_table(table_3);
891  share_2.destroy_table(table_5);
892 
893  table_cache_manager.unlock_all_and_tdc();
894 }
895 
896 
897 /*
898  Coverage for Table_cache_iterator
899 */
900 
901 TEST_F(TableCacheDoubleCacheTest, Iterator)
902 {
903  THD *thd_1= get_thd(0);
904  THD *thd_2= get_thd(1);
905 
906  table_cache_manager.lock_all_and_tdc();
907 
908  Mock_share share_1("share_1");
909  Mock_share share_2("share_2");
910 
911  // There is no TABLE objects for share_1 so the below iterator
912  // should not find anything.
913  Table_cache_iterator it(&share_1);
914  EXPECT_TRUE(it++ == NULL);
915  // Attempt to iterate behind the end should not give anything.
916  EXPECT_TRUE(it++ == NULL);
917 
918  Table_cache *table_cache_1= table_cache_manager.get_cache(thd_1);
919  Table_cache *table_cache_2= table_cache_manager.get_cache(thd_2);
920  TABLE *table_1= share_1.create_table(thd_1);
921  TABLE *table_2= share_1.create_table(thd_1);
922  TABLE *table_3= share_2.create_table(thd_1);
923  TABLE *table_4= share_1.create_table(thd_2);
924  TABLE *table_5= share_2.create_table(thd_2);
925 
926  table_cache_2->add_used_table(thd_2, table_4);
927 
928  // Now the iterato should see table_4.
929  it.rewind();
930  TABLE *table_r1= it++;
931  EXPECT_TRUE(table_r1 == table_4);
932  // But only it.
933  EXPECT_TRUE(it++ == NULL);
934  EXPECT_TRUE(it++ == NULL);
935 
936  table_cache_1->add_used_table(thd_1, table_1);
937 
938  // Now we should see two tables:
939  it.rewind();
940  table_r1= it++;
941  EXPECT_TRUE(table_r1 != NULL);
942  TABLE *table_r2= it++;
943  EXPECT_TRUE(table_r2 != NULL);
944  EXPECT_TRUE(table_r1 != table_r2);
945  EXPECT_TRUE(it++ == NULL);
946  EXPECT_TRUE(it++ == NULL);
947 
948  table_cache_1->add_used_table(thd_1, table_2);
949 
950  // And now three !
951  it.rewind();
952  table_r1= it++;
953  EXPECT_TRUE(table_r1 != NULL);
954  table_r2= it++;
955  EXPECT_TRUE(table_r2 != NULL);
956  TABLE *table_r3= it++;
957  EXPECT_TRUE(table_r3 != NULL);
958  EXPECT_TRUE(table_r1 != table_r2 && table_r1 != table_r3 && table_r2 != table_r3);
959  EXPECT_TRUE(it++ == NULL);
960  EXPECT_TRUE(it++ == NULL);
961 
962  table_cache_1->release_table(thd_1, table_1);
963 
964  // We should be seeing only used TABLE objects, so two tables now
965  it.rewind();
966  table_r1= it++;
967  EXPECT_TRUE(table_r1 != NULL);
968  table_r2= it++;
969  EXPECT_TRUE(table_r2 != NULL);
970  EXPECT_TRUE(table_r1 != table_r2);
971  EXPECT_TRUE(it++ == NULL);
972  EXPECT_TRUE(it++ == NULL);
973 
974  table_cache_1->add_used_table(thd_1, table_3);
975  table_cache_2->add_used_table(thd_2, table_5);
976 
977  // We also should not be seeing TABLE objects for share_2
978  it.rewind();
979  table_r1= it++;
980  EXPECT_TRUE(table_r1 != NULL);
981  table_r2= it++;
982  EXPECT_TRUE(table_r2 != NULL);
983  EXPECT_TRUE(table_r1 != table_r2);
984  EXPECT_TRUE(it++ == NULL);
985  EXPECT_TRUE(it++ == NULL);
986 
987  table_cache_1->remove_table(table_2);
988 
989  // Now we should se only one used TABLE
990  it.rewind();
991  table_r1= it++;
992  EXPECT_TRUE(table_r1 == table_4);
993  EXPECT_TRUE(it++ == NULL);
994  EXPECT_TRUE(it++ == NULL);
995 
996  table_cache_1->remove_table(table_4);
997 
998  // And now no used TABLE objects for share_1 at all
999  it.rewind();
1000  EXPECT_TRUE(it++ == NULL);
1001  EXPECT_TRUE(it++ == NULL);
1002 
1003  table_cache_1->remove_table(table_1);
1004 
1005  // Still the same
1006  it.rewind();
1007  EXPECT_TRUE(it++ == NULL);
1008  EXPECT_TRUE(it++ == NULL);
1009 
1010  table_cache_1->remove_table(table_3);
1011  table_cache_2->remove_table(table_5);
1012 
1013  // Cache is empty so iterator should not show any TABLE objects.
1014  it.rewind();
1015  EXPECT_TRUE(it++ == NULL);
1016  EXPECT_TRUE(it++ == NULL);
1017 
1018  table_cache_manager.unlock_all_and_tdc();
1019 
1020  share_1.destroy_table(table_1);
1021  share_1.destroy_table(table_2);
1022  share_2.destroy_table(table_3);
1023  share_1.destroy_table(table_4);
1024  share_2.destroy_table(table_5);
1025 }
1026 
1027 }