mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
77017191de
- serializing calls to flush_pagecache_blocks_int() on the same file to avoid known concurrency bugs - having that, we can now enable the background thread, as the flushes it does are now supposedly safe in concurrent situations. - new type of flush FLUSH_KEEP_LAZY: when the background checkpoint thread is flushing a packet of dirty pages between two checkpoints, it uses this flush type, indeed if a file is already being flushed by another thread it's smarter to move on to the next file than wait. - maria_checkpoint_frequency renamed to maria_checkpoint_interval. include/my_sys.h: new type of flushing for the page cache: FLUSH_KEEP_LAZY mysql-test/r/maria.result: result update mysys/mf_keycache.c: indentation. No FLUSH_KEEP_LAZY support in key cache. storage/maria/ha_maria.cc: maria_checkpoint_frequency was somehow a hidden part of the Checkpoint API and that was not good. Now we have checkpoint_interval, local to ha_maria.cc, which serves as container for the user-visible maria_checkpoint_interval global variable; setting it calls update_checkpoint_interval which passes the new value to ma_checkpoint_init(). There is no hiding anymore. By default, enable background thread which does checkpoints every 30 seconds, and dirty page flush in between. That thread takes a checkpoint when it ends, so no need for maria_hton_panic to take one. The | is | and not ||, because maria_panic() must always be called. frequency->interval. storage/maria/ma_checkpoint.c: Use FLUSH_KEEP_LAZY for background thread when it flushes packets of dirty pages between two checkpoints: it is smarter to move on to the next file than wait for it to have been completely flushed, which may take long. Comments about flush concurrency bugs moved from ma_pagecache.c. Removing out-of-date comment. frequency->interval. create_background_thread -> (interval>0). In ma_checkpoint_background(), some variables need to be preserved between iterations. storage/maria/ma_checkpoint.h: new prototype storage/maria/ma_pagecache.c: - concurrent calls of flush_pagecache_blocks_int() on the same file cause bugs (see @note in that function); we fix them by serializing in this situation. For that we use a global hash of (file, wqueue). When flush_pagecache_blocks_int() starts it looks into the hash, using the file as key. If not found, it inserts (file,wqueue) into the hash, flushes the file, and finally removes itself from the hash and wakes up any waiter in the queue. If found, it adds itself to the wqueue and waits. - As a by-product, we can remove changed_blocks_is_incomplete and replace it by scanning the hash, replace the sleep() by a queue wait. - new type of flush FLUSH_KEEP_LAZY: when flushing a file, if it's already being flushed by another thread (even partially), return immediately. storage/maria/ma_pagecache.h: In pagecache, a hash of files currently being flushed (i.e. there is a call to flush_pagecache_blocks_int() for them). storage/maria/ma_recovery.c: new prototype storage/maria/ma_test1.c: new prototype storage/maria/ma_test2.c: new prototype
81 lines
2.9 KiB
C
81 lines
2.9 KiB
C
/* Copyright (C) 2006,2007 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
/*
|
|
WL#3071 Maria checkpoint
|
|
First version written by Guilhem Bichot on 2006-04-27.
|
|
Does not compile yet.
|
|
*/
|
|
|
|
/* This is the interface of this module. */
|
|
|
|
typedef enum enum_ma_checkpoint_level {
|
|
CHECKPOINT_NONE= 0,
|
|
/* just write dirty_pages, transactions table and sync files */
|
|
CHECKPOINT_INDIRECT,
|
|
/* also flush all dirty pages which were already dirty at prev checkpoint */
|
|
CHECKPOINT_MEDIUM,
|
|
/* also flush all dirty pages */
|
|
CHECKPOINT_FULL
|
|
} CHECKPOINT_LEVEL;
|
|
|
|
C_MODE_START
|
|
int ma_checkpoint_init(ulong interval);
|
|
void ma_checkpoint_end(void);
|
|
int ma_checkpoint_execute(CHECKPOINT_LEVEL level, my_bool no_wait);
|
|
C_MODE_END
|
|
|
|
/**
|
|
@brief reads some LSNs with special trickery
|
|
|
|
If a 64-bit variable transitions between both halves being zero to both
|
|
halves being non-zero, and back, this function can be used to do a read of
|
|
it (without mutex, without atomic load) which always produces a correct
|
|
(though maybe slightly old) value (even on 32-bit CPUs). The value is at
|
|
least as new as the latest mutex unlock done by the calling thread.
|
|
The assumption is that the system sets both 4-byte halves either at the
|
|
same time, or one after the other (in any order), but NOT some bytes of the
|
|
first half then some bytes of the second half then the rest of bytes of the
|
|
first half. With this assumption, the function can detect when it is
|
|
seeing an inconsistent value.
|
|
|
|
@param LSN pointer to the LSN variable to read
|
|
|
|
@return LSN part (most significant byte always 0)
|
|
*/
|
|
#if ( SIZEOF_CHARP >= 8 )
|
|
/* 64-bit CPU, 64-bit reads are atomic */
|
|
#define lsn_read_non_atomic LSN_WITH_FLAGS_TO_LSN
|
|
#else
|
|
static inline LSN lsn_read_non_atomic_32(const volatile LSN *x)
|
|
{
|
|
/*
|
|
32-bit CPU, 64-bit reads may give a mixed of old half and new half (old
|
|
low bits and new high bits, or the contrary).
|
|
*/
|
|
for (;;) /* loop until no atomicity problems */
|
|
{
|
|
/*
|
|
Remove most significant byte in case this is a LSN_WITH_FLAGS object.
|
|
Those flags in TRN::first_undo_lsn break the condition on transitions so
|
|
they must be removed below.
|
|
*/
|
|
LSN y= LSN_WITH_FLAGS_TO_LSN(*x);
|
|
if (likely((y == LSN_IMPOSSIBLE) || LSN_VALID(y)))
|
|
return y;
|
|
}
|
|
}
|
|
#define lsn_read_non_atomic(x) lsn_read_non_atomic_32(&x)
|
|
#endif
|