diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 59289f9321bc8808e6013c9f90e0dd0528541707..405c39cde86d7d23c9b17583b4422588ae0de5d2 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -2029,14 +2029,21 @@ vy_begin(struct vy_env *env) int vy_prepare(struct vy_env *env, struct vy_tx *tx) { + /* + * A replica receives a lot of data during initial join. + * If the network connection is fast enough, it might fail + * to keep up with dumps. To avoid replication failure due + * to this, we ignore the quota timeout during bootstrap. + */ + double timeout = (env->status == VINYL_ONLINE ? + env->timeout : TIMEOUT_INFINITY); /* * Reserve quota needed by the transaction before allocating * memory. Since this may yield, which opens a time window for * the transaction to be sent to read view or aborted, we call * it before checking for conflicts. */ - if (vy_quota_use(&env->quota, tx->write_size, - env->timeout) != 0) { + if (vy_quota_use(&env->quota, tx->write_size, timeout) != 0) { diag_set(ClientError, ER_VY_QUOTA_TIMEOUT); return -1; } diff --git a/test/vinyl/join_quota.lua b/test/vinyl/join_quota.lua index 14250a93b8efd56650875284729b4869d3e6a6d0..d371abf14f210655abe6f1cf9be77ad457c0ec52 100644 --- a/test/vinyl/join_quota.lua +++ b/test/vinyl/join_quota.lua @@ -4,6 +4,7 @@ box.cfg({ listen = os.getenv("LISTEN"), replication = os.getenv("MASTER"), vinyl_memory = 1024 * 1024, + vinyl_timeout = 0.001, }) require('console').listen(os.getenv('ADMIN')) diff --git a/test/vinyl/replica_quota.result b/test/vinyl/replica_quota.result index d2f3c650a4fbe73da338b11f5907b79498c4ed1d..485efde79f0179e0bcdce2bfb0307eb98e2a35b0 100644 --- a/test/vinyl/replica_quota.result +++ b/test/vinyl/replica_quota.result @@ -29,6 +29,13 @@ for i = 1001,2000 do s:insert{i, pad} end ... -- Replica has memory limit set to 1 MB so replication would hang -- if the scheduler didn't work on the destination. +-- +-- Also check that quota timeout isn't taken into account while +-- the replica is joining (see gh-2873). To do that, we set +-- vinyl_timeout to 1 ms on the replica, which isn't enough for +-- a dump to complete and hence would result in bootstrap failure +-- were the timeout not ignored. +-- _ = test_run:cmd("create server replica with rpl_master=default, script='vinyl/join_quota.lua'") --- ... diff --git a/test/vinyl/replica_quota.test.lua b/test/vinyl/replica_quota.test.lua index f9215c2203cbf07cc4cf7c93440c24d85dd951fd..bc6cfb0d71d0eaff900ca15ab0b4af653d294918 100644 --- a/test/vinyl/replica_quota.test.lua +++ b/test/vinyl/replica_quota.test.lua @@ -14,6 +14,13 @@ for i = 1001,2000 do s:insert{i, pad} end -- Replica has memory limit set to 1 MB so replication would hang -- if the scheduler didn't work on the destination. +-- +-- Also check that quota timeout isn't taken into account while +-- the replica is joining (see gh-2873). To do that, we set +-- vinyl_timeout to 1 ms on the replica, which isn't enough for +-- a dump to complete and hence would result in bootstrap failure +-- were the timeout not ignored. +-- _ = test_run:cmd("create server replica with rpl_master=default, script='vinyl/join_quota.lua'") _ = test_run:cmd("start server replica") _ = test_run:wait_lsn('replica', 'default')