Improve scalability of WAL insertions.

This patch replaces WALInsertLock with a number of WAL insertion slots,
allowing multiple backends to insert WAL records to the WAL buffers
concurrently. This is particularly useful for parallel loading large amounts
of data on a system with many CPUs.

This has one user-visible change: switching to a new WAL segment with
pg_switch_xlog() now fills the remaining unused portion of the segment with
zeros. This potentially adds some overhead, but it has been a very common
practice by DBA's to clear the "tail" of the segment with an external
pg_clearxlogtail utility anyway, to make the WAL files compress better.
With this patch, it's no longer necessary to do that.

This patch adds a new GUC, xloginsert_slots, to tune the number of WAL
insertion slots. Performance testing suggests that the default, 8, works
pretty well for all kinds of worklods, but I left the GUC in place to allow
others with different hardware to test that easily. We might want to remove
that before release.

Reviewed by Andres Freund.
pull/6/head
Heikki Linnakangas 12 years ago
parent 5372275b4b
commit 9a20a9b21b
  1. 2111
      src/backend/access/transam/xlog.c
  2. 2
      src/backend/storage/lmgr/spin.c
  3. 11
      src/backend/utils/misc/guc.c
  4. 1
      src/include/access/xlog.h
  5. 10
      src/include/access/xlogdefs.h
  6. 2
      src/include/storage/lwlock.h

File diff suppressed because it is too large Load Diff

@ -22,6 +22,7 @@
*/
#include "postgres.h"
#include "access/xlog.h"
#include "miscadmin.h"
#include "replication/walsender.h"
#include "storage/lwlock.h"
@ -63,6 +64,7 @@ SpinlockSemas(void)
nsemas = NumLWLocks(); /* one for each lwlock */
nsemas += NBuffers; /* one for each buffer header */
nsemas += max_wal_senders; /* one for each wal sender process */
nsemas += num_xloginsert_slots; /* one for each WAL insertion slot */
nsemas += 30; /* plus a bunch for other small-scale use */
return nsemas;

@ -2037,6 +2037,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
{
{"xloginsert_slots", PGC_POSTMASTER, WAL_SETTINGS,
gettext_noop("Sets the number of slots for concurrent xlog insertions."),
NULL,
GUC_NOT_IN_SAMPLE
},
&num_xloginsert_slots,
8, 1, 1000,
NULL, NULL, NULL
},
{
/* see max_connections */
{"max_wal_senders", PGC_POSTMASTER, REPLICATION_SENDING,

@ -190,6 +190,7 @@ extern char *XLogArchiveCommand;
extern bool EnableHotStandby;
extern bool fullPageWrites;
extern bool log_checkpoints;
extern int num_xloginsert_slots;
/* WAL levels */
typedef enum WalLevel

@ -93,14 +93,4 @@ typedef uint32 TimeLineID;
#define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC
#endif
/*
* Limitation of buffer-alignment for direct IO depends on OS and filesystem,
* but XLOG_BLCKSZ is assumed to be enough for it.
*/
#ifdef O_DIRECT
#define ALIGNOF_XLOG_BUFFER XLOG_BLCKSZ
#else
#define ALIGNOF_XLOG_BUFFER ALIGNOF_BUFFER
#endif
#endif /* XLOG_DEFS_H */

@ -53,7 +53,7 @@ typedef enum LWLockId
ProcArrayLock,
SInvalReadLock,
SInvalWriteLock,
WALInsertLock,
WALBufMappingLock,
WALWriteLock,
ControlFileLock,
CheckpointLock,

Loading…
Cancel
Save