Skip to content

Commit 831c22a

Browse files
AliSQLAliSQL
authored andcommitted
[Feature] Issue#26 ADD TokuDB 7.5.3 SUPPORT
1 parent 2bd2180 commit 831c22a

1,641 files changed

Lines changed: 431619 additions & 38 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

sql/handler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1862,7 +1862,7 @@ int ha_recover(HASH *commit_list)
18621862
if (info.commit_list)
18631863
sql_print_information("Starting crash recovery...");
18641864

1865-
#ifndef WILL_BE_DELETED_LATER
1865+
#if (0)
18661866
/*
18671867
for now, only InnoDB supports 2pc. It means we can always safely
18681868
rollback all pending transactions, without risking inconsistent data

sql/handler.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ enum legacy_db_type
393393
DB_TYPE_MARIA,
394394
/** Performance schema engine. */
395395
DB_TYPE_PERFORMANCE_SCHEMA,
396+
DB_TYPE_TOKUDB=41,
396397
DB_TYPE_FIRST_DYNAMIC=42,
397398
DB_TYPE_DEFAULT=127 // Must be last
398399
};
@@ -401,7 +402,11 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
401402
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
402403
ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
403404
/** Unused. Reserved for future versions. */
404-
ROW_TYPE_PAGE };
405+
ROW_TYPE_PAGE,
406+
ROW_TYPE_TOKU_UNCOMPRESSED, ROW_TYPE_TOKU_ZLIB,
407+
ROW_TYPE_TOKU_QUICKLZ, ROW_TYPE_TOKU_LZMA,
408+
ROW_TYPE_TOKU_FAST, ROW_TYPE_TOKU_SMALL };
409+
405410

406411
/* Specifies data storage format for individual columns */
407412
enum column_format_type {

sql/log.cc

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,7 +2530,8 @@ int TC_LOG_MMAP::open(const char *opt_name)
25302530
inited=2;
25312531

25322532
npages=(uint)file_length/tc_log_page_size;
2533-
DBUG_ASSERT(npages >= 3); // to guarantee non-empty pool
2533+
if (npages < 3) // to guarantee non-empty pool
2534+
goto err;
25342535
if (!(pages=(PAGE *)my_malloc(npages*sizeof(PAGE), MYF(MY_WME|MY_ZEROFILL))))
25352536
goto err;
25362537
inited=3;
@@ -2541,9 +2542,9 @@ int TC_LOG_MMAP::open(const char *opt_name)
25412542
pg->state=PS_POOL;
25422543
mysql_mutex_init(key_PAGE_lock, &pg->lock, MY_MUTEX_INIT_FAST);
25432544
mysql_cond_init(key_PAGE_cond, &pg->cond, 0);
2544-
pg->start=(my_xid *)(data + i*tc_log_page_size);
2545-
pg->end=(my_xid *)(pg->start + tc_log_page_size);
2545+
pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
25462546
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
2547+
pg->end= pg->start + pg->size;
25472548
}
25482549
pages[0].size=pages[0].free=
25492550
(tc_log_page_size-TC_LOG_HEADER_SIZE)/sizeof(my_xid);
@@ -2569,8 +2570,9 @@ int TC_LOG_MMAP::open(const char *opt_name)
25692570

25702571
syncing= 0;
25712572
active=pages;
2573+
DBUG_ASSERT(npages >= 2);
25722574
pool=pages+1;
2573-
pool_last=pages+npages-1;
2575+
pool_last_ptr= &((pages+npages-1)->next);
25742576

25752577
return 0;
25762578

@@ -2579,6 +2581,16 @@ int TC_LOG_MMAP::open(const char *opt_name)
25792581
return 1;
25802582
}
25812583

2584+
/**
2585+
Get the total amount of potentially usable slots for XIDs in TC log.
2586+
*/
2587+
2588+
uint TC_LOG_MMAP::size() const
2589+
{
2590+
return (tc_log_page_size-TC_LOG_HEADER_SIZE)/sizeof(my_xid) +
2591+
(npages - 1) * (tc_log_page_size/sizeof(my_xid));
2592+
}
2593+
25822594
/**
25832595
there is no active page, let's got one from the pool.
25842596
@@ -2596,13 +2608,11 @@ void TC_LOG_MMAP::get_active_from_pool()
25962608
PAGE **p, **best_p=0;
25972609
int best_free;
25982610

2599-
if (syncing)
2600-
mysql_mutex_lock(&LOCK_pool);
2601-
2611+
mysql_mutex_lock(&LOCK_pool);
26022612
do
26032613
{
26042614
best_p= p= &pool;
2605-
if ((*p)->waiters == 0) // can the first page be used ?
2615+
if ((*p)->waiters == 0 && (*p)->free > 0) // can the first page be used ?
26062616
break; // yes - take it.
26072617

26082618
best_free=0; // no - trying second strategy
@@ -2617,20 +2627,21 @@ void TC_LOG_MMAP::get_active_from_pool()
26172627
}
26182628
while ((*best_p == 0 || best_free == 0) && overflow());
26192629

2630+
mysql_mutex_assert_owner(&LOCK_active);
26202631
active=*best_p;
2632+
2633+
/* Unlink the page from the pool. */
2634+
if (!(*best_p)->next)
2635+
pool_last_ptr= best_p;
2636+
*best_p=(*best_p)->next;
2637+
mysql_mutex_unlock(&LOCK_pool);
2638+
2639+
mysql_mutex_lock(&active->lock);
26212640
if (active->free == active->size) // we've chosen an empty page
26222641
{
2623-
tc_log_cur_pages_used++;
2642+
thread_safe_increment(tc_log_cur_pages_used, &LOCK_status);
26242643
set_if_bigger(tc_log_max_pages_used, tc_log_cur_pages_used);
26252644
}
2626-
2627-
if ((*best_p)->next) // unlink the page from the pool
2628-
*best_p=(*best_p)->next;
2629-
else
2630-
pool_last=*best_p;
2631-
2632-
if (syncing)
2633-
mysql_mutex_unlock(&LOCK_pool);
26342645
}
26352646

26362647
/**
@@ -2663,7 +2674,7 @@ TC_LOG::enum_result TC_LOG_MMAP::commit(THD *thd, bool all)
26632674
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
26642675

26652676
if (all && xid)
2666-
if ((cookie= log_xid(thd, xid)))
2677+
if (!(cookie= log_xid(thd, xid)))
26672678
DBUG_RETURN(RESULT_ABORTED); // Failed to log the transaction
26682679

26692680
if (ha_commit_low(thd, all))
@@ -2725,9 +2736,17 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
27252736
/* no active page ? take one from the pool */
27262737
if (active == 0)
27272738
get_active_from_pool();
2739+
else
2740+
mysql_mutex_lock(&active->lock);
27282741

27292742
p=active;
2730-
mysql_mutex_lock(&p->lock);
2743+
2744+
/*
2745+
p->free is always > 0 here because to decrease it one needs
2746+
to take p->lock and before it one needs to take LOCK_active.
2747+
But checked that active->free > 0 under LOCK_active and
2748+
haven't release it ever since
2749+
*/
27312750

27322751
/* searching for an empty slot */
27332752
while (*p->ptr)
@@ -2742,37 +2761,49 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
27422761
p->free--;
27432762
p->state= PS_DIRTY;
27442763

2745-
/* to sync or not to sync - this is the question */
2746-
mysql_mutex_unlock(&LOCK_active);
2747-
mysql_mutex_lock(&LOCK_sync);
27482764
mysql_mutex_unlock(&p->lock);
2749-
2765+
mysql_mutex_lock(&LOCK_sync);
27502766
if (syncing)
27512767
{ // somebody's syncing. let's wait
2768+
mysql_mutex_unlock(&LOCK_active);
2769+
mysql_mutex_lock(&p->lock);
27522770
p->waiters++;
27532771
/*
27542772
note - it must be while (), not do ... while () here
27552773
as p->state may be not PS_DIRTY when we come here
27562774
*/
27572775
while (p->state == PS_DIRTY && syncing)
2776+
{
2777+
mysql_mutex_unlock(&p->lock);
27582778
mysql_cond_wait(&p->cond, &LOCK_sync);
2779+
mysql_mutex_lock(&p->lock);
2780+
}
27592781
p->waiters--;
27602782
err= p->state == PS_ERROR;
27612783
if (p->state != PS_DIRTY) // page was synced
27622784
{
2785+
mysql_mutex_unlock(&LOCK_sync);
27632786
if (p->waiters == 0)
27642787
mysql_cond_signal(&COND_pool); // in case somebody's waiting
2765-
mysql_mutex_unlock(&LOCK_sync);
2788+
mysql_mutex_unlock(&p->lock);
27662789
goto done; // we're done
27672790
}
2768-
} // page was not synced! do it now
2769-
DBUG_ASSERT(active == p && syncing == 0);
2770-
mysql_mutex_lock(&LOCK_active);
2771-
syncing=p; // place is vacant - take it
2791+
DBUG_ASSERT(!syncing);
2792+
mysql_mutex_unlock(&p->lock);
2793+
syncing = p;
2794+
mysql_mutex_unlock(&LOCK_sync);
2795+
2796+
mysql_mutex_lock(&LOCK_active);
2797+
}
2798+
else
2799+
{
2800+
syncing= p; // place is vacant - take it
2801+
mysql_mutex_unlock(&LOCK_sync);
2802+
}
2803+
27722804
active=0; // page is not active anymore
27732805
mysql_cond_broadcast(&COND_active); // in case somebody's waiting
27742806
mysql_mutex_unlock(&LOCK_active);
2775-
mysql_mutex_unlock(&LOCK_sync);
27762807
err= sync();
27772808

27782809
done:
@@ -2789,22 +2820,32 @@ int TC_LOG_MMAP::sync()
27892820
sit down and relax - this can take a while...
27902821
note - no locks are held at this point
27912822
*/
2792-
err= my_msync(fd, syncing->start, 1, MS_SYNC);
2823+
err= my_msync(fd, syncing->start, syncing->size * sizeof(my_xid), MS_SYNC);
27932824

27942825
/* page is synced. let's move it to the pool */
27952826
mysql_mutex_lock(&LOCK_pool);
2796-
pool_last->next=syncing;
2797-
pool_last=syncing;
2827+
(*pool_last_ptr)= syncing;
2828+
pool_last_ptr= &(syncing->next);
27982829
syncing->next=0;
27992830
syncing->state= err ? PS_ERROR : PS_POOL;
2800-
mysql_cond_broadcast(&syncing->cond); // signal "sync done"
28012831
mysql_cond_signal(&COND_pool); // in case somebody's waiting
28022832
mysql_mutex_unlock(&LOCK_pool);
28032833

28042834
/* marking 'syncing' slot free */
28052835
mysql_mutex_lock(&LOCK_sync);
2836+
mysql_cond_broadcast(&syncing->cond); // signal "sync done"
28062837
syncing=0;
2807-
mysql_cond_signal(&active->cond); // wake up a new syncer
2838+
2839+
/*
2840+
we check the "active" pointer without LOCK_active. Still, it's safe -
2841+
"active" can change from NULL to not NULL any time, but it
2842+
will take LOCK_sync before waiting on active->cond. That is, it can never
2843+
miss a signal.
2844+
And "active" can change to NULL only by the syncing thread
2845+
(the thread that will send a signal below)
2846+
*/
2847+
if (active)
2848+
mysql_cond_signal(&active->cond); // wake up a new syncer
28082849
mysql_mutex_unlock(&LOCK_sync);
28092850
return err;
28102851
}
@@ -2821,9 +2862,9 @@ int TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
28212862

28222863
DBUG_ASSERT(*x == xid);
28232864
DBUG_ASSERT(x >= p->start && x < p->end);
2824-
*x=0;
28252865

28262866
mysql_mutex_lock(&p->lock);
2867+
*x=0;
28272868
p->free++;
28282869
DBUG_ASSERT(p->free <= p->size);
28292870
set_if_smaller(p->ptr, x);

sql/log.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class TC_LOG_MMAP: public TC_LOG
149149
my_off_t file_length;
150150
uint npages, inited;
151151
uchar *data;
152-
struct st_page *pages, *syncing, *active, *pool, *pool_last;
152+
struct st_page *pages, *syncing, *active, *pool, **pool_last_ptr;
153153
/*
154154
note that, e.g. LOCK_active is only used to protect
155155
'active' pointer, to protect the content of the active page
@@ -167,13 +167,15 @@ class TC_LOG_MMAP: public TC_LOG
167167
int rollback(THD *thd, bool all) { return ha_rollback_low(thd, all); }
168168
int prepare(THD *thd, bool all) { return ha_prepare_low(thd, all); }
169169
int recover();
170+
uint size() const;
170171

171172
private:
172173
int log_xid(THD *thd, my_xid xid);
173174
int unlog(ulong cookie, my_xid xid);
174175
void get_active_from_pool();
175176
int sync();
176177
int overflow();
178+
friend class TCLogMMapTest;
177179
};
178180
#else
179181
#define TC_LOG_MMAP TC_LOG_DUMMY

storage/innobase/handler/ha_innodb.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9122,6 +9122,7 @@ get_row_format_name(
91229122
return("FIXED");
91239123
case ROW_TYPE_PAGE:
91249124
case ROW_TYPE_NOT_USED:
9125+
default:
91259126
break;
91269127
}
91279128
return("NOT USED");
@@ -9267,6 +9268,7 @@ create_options_are_invalid(
92679268
case ROW_TYPE_FIXED:
92689269
case ROW_TYPE_PAGE:
92699270
case ROW_TYPE_NOT_USED:
9271+
default:
92709272
push_warning(
92719273
thd, Sql_condition::WARN_LEVEL_WARN,
92729274
ER_ILLEGAL_HA_CREATE_OPTION, \
@@ -9640,6 +9642,7 @@ innobase_table_flags(
96409642
case ROW_TYPE_NOT_USED:
96419643
case ROW_TYPE_FIXED:
96429644
case ROW_TYPE_PAGE:
9645+
default:
96439646
push_warning(
96449647
thd, Sql_condition::WARN_LEVEL_WARN,
96459648
ER_ILLEGAL_HA_CREATE_OPTION,

0 commit comments

Comments
 (0)