!! Changed db_preallocation to False

Long explanation, but hopefully answers any questions.

We don't like changing the default behavior of Swift unless there's a
really good reason and, up until now, I've tried doing this with this
new db_preallocation setting.

For clusters with dedicated account/container servers that usually
have fewer disks overall but SSD for speed, having db_preallocation
on will gobble up disk space quite quickly and the fragmentation it's
designed to fight isn't that big a speed impact to SSDs anyway.

For clusters with account/container servers spread across all servers
along with object servers usually having standard disks for cost,
having db_preallocation off will cause very fragmented database files
impacting speed, sometimes dramatically.

Weighing these two negatives, it seems the second is the lesser evil.
The first can cause disks to fill up and disable the cluster. The
second will cause performance degradation, but the cluster will still
function.

Furthermore, if just one piece of code that touches all databases
runs with db_preallocation on, it's effectively on for the whole
cluster. We discovered this most recently when we finally configured
everything within the Swift codebase to have db_preallocation off,
only to find out Slogging didn't know about the new setting and so
ran with it on and starting filling up SSDs.

So that's why I'm proposing this change to the default behavior.

We will definitely need to post a prominent notice of this change
with the next release.

Change-Id: I48a43439264cff5d03c14ec8787f718ee44e78ea
This commit is contained in:
gholt 2012-05-22 00:30:47 +00:00
parent 1c3b75c291
commit 9eb797b099
12 changed files with 20 additions and 22 deletions

View File

@ -425,10 +425,10 @@ bind_ip 0.0.0.0 IP Address for server to bind to
bind_port 6002 Port for server to bind to
workers 1 Number of workers to fork
user swift User to run as
db_preallocation on Normally Swift will try to preallocate disk
space for new SQLite databases to decrease
fragmentation (at the cost of disk usage). You
may turn this feature off here.
db_preallocation off If you don't mind the extra disk space usage in
overhead, you can turn this on to preallocate
disk space with SQLite databases to decrease
fragmentation.
================== ========== =============================================
[account-server]

View File

@ -17,10 +17,9 @@
# log_statsd_port = 8125
# log_statsd_default_sample_rate = 1
# log_statsd_metric_prefix =
# Normally Swift will try to preallocate disk space for new SQLite databases to
# decrease fragmentation (at the cost of disk usage). You may turn this feature
# off here.
# db_preallocation = on
# If you don't mind the extra disk space usage in overhead, you can turn this
# on to preallocate disk space with SQLite databases to decrease fragmentation.
# db_preallocation = off
[pipeline:main]
pipeline = account-server

View File

@ -20,10 +20,9 @@
# log_statsd_port = 8125
# log_statsd_default_sample_rate = 1
# log_statsd_metric_prefix =
# Normally Swift will try to preallocate disk space for new SQLite databases to
# decrease fragmentation (at the cost of disk usage). You may turn this feature
# off here.
# db_preallocation = on
# If you don't mind the extra disk space usage in overhead, you can turn this
# on to preallocate disk space with SQLite databases to decrease fragmentation.
# db_preallocation = off
[pipeline:main]
pipeline = container-server

View File

@ -39,7 +39,7 @@ class AccountAuditor(Daemon):
self.account_passes = 0
self.account_failures = 0
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def _one_audit_pass(self, reported):
all_locs = audit_location_generator(self.devices,

View File

@ -71,7 +71,7 @@ class AccountReaper(Daemon):
sqrt(self.concurrency)
self.container_pool = GreenPool(size=self.container_concurrency)
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
self.delay_reaping = int(conf.get('delay_reaping') or 0)
def get_account_ring(self):

View File

@ -55,7 +55,7 @@ class AccountController(object):
self.auto_create_account_prefix = \
conf.get('auto_create_account_prefix') or '.'
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def _get_account_broker(self, drive, part, account):
hsh = hash_path(account)

View File

@ -122,7 +122,7 @@ class Replicator(Daemon):
self.conn_timeout = float(conf.get('conn_timeout', 0.5))
self.reclaim_age = float(conf.get('reclaim_age', 86400 * 7))
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
self._zero_stats()
def _zero_stats(self):

View File

@ -40,7 +40,7 @@ class ContainerAuditor(Daemon):
self.container_passes = 0
self.container_failures = 0
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def _one_audit_pass(self, reported):
all_locs = audit_location_generator(self.devices,

View File

@ -69,7 +69,7 @@ class ContainerController(object):
if conf.get('allow_versions', 'f').lower() in TRUE_VALUES:
self.save_headers.append('x-versions-location')
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def _get_container_broker(self, drive, part, account, container):
"""

View File

@ -180,7 +180,7 @@ class ContainerSync(Daemon):
self._myips = whataremyips()
self._myport = int(conf.get('bind_port', 6001))
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def run_forever(self):
"""

View File

@ -58,7 +58,7 @@ class ContainerUpdater(Daemon):
float(conf.get('account_suppression_time', 60))
self.new_account_suppressions = None
swift.common.db.DB_PREALLOCATION = \
conf.get('db_preallocation', 't').lower() in TRUE_VALUES
conf.get('db_preallocation', 'f').lower() in TRUE_VALUES
def get_account_ring(self):
"""Get the account ring. Load it if it hasn't been yet."""

View File

@ -100,9 +100,9 @@ class TestDatabaseBroker(unittest.TestCase):
def test_DB_PREALLOCATION_setting(self):
u = uuid4().hex
b = DatabaseBroker(u)
self.assertRaises(OSError, b._preallocate)
swift.common.db.DB_PREALLOCATION = False
b._preallocate()
swift.common.db.DB_PREALLOCATION = True
self.assertRaises(OSError, b._preallocate)
def tearDown(self):
rmtree(self.testdir, ignore_errors=1)