Commit graph

252 commits

Author SHA1 Message Date
Reedy
71badb429e Remove global namespaced LBFactory
Change-Id: Ia87aa5c9426af83627a1bbc9bd914546c89c1e47
2018-09-21 15:42:42 +00:00
Reedy
1c5399b471 tests: Stop using deprecated LBFactory, use namespaced version
Change-Id: Ifbbbfe1bc58e57739b88588e3b6feb703f20534d
2018-09-21 02:37:12 +00:00
Aaron Schulz
5938a6efdc rdbms: add more comments and sanity checks for CONN_TRX_AUTOCOMMIT
Change-Id: I69992cf2e2ae3ef62125b0bc733a0cb7274f814e
2018-08-09 01:39:07 +00:00
Kunal Mehta
b92565ca18 Disable PHPUnit tests that fail under sqlite
So we can make the job voting, preventing other tests from regressing.
These tests can be re-enabled whenever they're made to pass.

Change-Id: I959710138e1e1b37b6ba69561c2920a78208bf12
2018-08-01 00:19:43 -07:00
Aaron Schulz
2fd62f5dc9 rdbms: add resolveDomainID() method to LBFactory/LoadBalancer
Also add LBFactory::getLocalDomainID to match the one in LoadBalancer

Change-Id: Ia31f0800bd3b692194c08b1eab9cfb2f43679c7a
2018-07-05 14:07:04 +01:00
jenkins-bot
4b5773a4de Merge "rdbms: fix Sqlite::tableExists() method to avoid STATUS_TRX_ERROR" 2018-07-03 05:40:03 +00:00
Aaron Schulz
d16bfb0a30 rdbms: fix Sqlite::tableExists() method to avoid STATUS_TRX_ERROR
Sqlite used the base implementation of trying a SELECT 1 query and
seeing if it failed. Instead, make it use the sqlite_master table.
Also remove the base version of that method since it would always
cause this problem and all subclasses have proper implementations.

Make LoadBalancerTest::assertWriteAllowed() more explicit and add
more assertions there.

Change-Id: I6c7b0bea8894c45dfe8931748d6687f0e5d1e101
2018-06-22 22:33:45 +00:00
Aaron Schulz
44b47b43ee rdbms: make getCPInfoFromCookieValue() stricter about allowed values
All components, not just the write index, must now be present.

Bug: T194403
Change-Id: I279ba3e16d470aca09fdb74cec91d28efb5e2f95
2018-06-12 18:18:54 +00:00
Aaron Schulz
fb51330084 rdbms: include client ID hash in ChronologyProtector cookies
Previously, if an internal service forwarded the cookies for a
user (e.g. for permissions) but not the User-Agent header or not
the IP address (e.g. XFF), ChronologyProtector could timeout
waiting for a matching writeIndex to appear for the wrong key.

The cookie now tethers the client to the key that holds the
DB positions from their last state-changing request.

Bug: T194403
Bug: T190082
Change-Id: I84f2cbea82532d911cdfed14644008894498813a
2018-06-02 03:57:30 +00:00
Bartosz Dziewoński
485f66f174 Use PHP 7 '??' operator instead of '?:' with 'isset()' where convenient
Find: /isset\(\s*([^()]+?)\s*\)\s*\?\s*\1\s*:\s*/
Replace with: '\1 ?? '

(Everywhere except includes/PHPVersionCheck.php)
(Then, manually fix some line length and indentation issues)

Then manually reviewed the replacements for cases where confusing
operator precedence would result in incorrect results
(fixing those in I478db046a1cc162c6767003ce45c9b56270f3372).

Change-Id: I33b421c8cb11cdd4ce896488c9ff5313f03a38cf
2018-05-30 18:06:13 -07:00
Aaron Schulz
52af356cad Avoid unnecessary WaitConditionLoop delays in ChronologyProtector
Since it takes time for the agent to get the response and set the
cookie and, as well, the time into a request that a LoadBalancer is
initialized varies by many seconds (cookies loaded from the start),
give the cookie a much lower TTL than the DB positions in the stash.

This avoids having to wait for a position with a given cpPosIndex
value, when the position already expired from the store, which is
a waste of time.

Also include the timestamp in "cpPosIndex" cookies to implement
logical expiration in case clients do not expire them correctly.

Bug: T194403
Bug: T190082
Change-Id: I97d8f108dec59c5ccead66432a097cda8ef4a178
2018-05-18 13:43:05 -07:00
jenkins-bot
da0c275136 Merge "rdbms: fix callback stage errors in LBFactory::commitMasterChanges" 2018-05-10 19:07:18 +00:00
Aaron Schulz
86af2ef383 rdbms: fix callback stage errors in LBFactory::commitMasterChanges
Just like 082ed053b6 fixed pre-commit callback errors when new instances
of LoadBalancer are made during that step, do the same for post-commit
callbacks.

Bug: T194308
Change-Id: Ie79e0f22b3aced425cf067d0df6b67e368223e6c
2018-05-10 04:26:41 +00:00
jenkins-bot
aae58f60d5 Merge "rdbms: rename onTransactionIdle() to onTransactionCommitOrIdle()" 2018-05-09 22:36:44 +00:00
Aaron Schulz
205cfc1854 rdbms: fix LBFactory::commitAll() round handling
This avoids "Transaction round stage must be approved (not cursory)".

Bug: T194308
Change-Id: I9dbfe9cede02b1b1904c1d5e5a9802306c2492a2
2018-05-09 14:51:18 -07:00
Aaron Schulz
b6cd5421b9 rdbms: rename onTransactionIdle() to onTransactionCommitOrIdle()
This is clearer and is consistent with onTransactionPreCommitOrIdle()

Change-Id: I3a34a0e9adea69ec55ed6ddfef47703e31e7c3b5
2018-05-09 21:07:06 +00:00
Aaron Schulz
082ed053b6 rdbms: fix finalization stage errors in LBFactory::commitMasterChanges
If a pre-commit callback caused a new LoadBalancer object to be created,
that object will be in the "cursory" state rather than the "finalized"
state. If any callbacks run on an LB instance, make LBFactory iterate
over them all again to finalize these new instances.

Make LoadBalancer::finializeMasterChanges allow calls to
already-finalized instances for simplicity.

Bug: T193668
Change-Id: I4493e9571625a350c0a102219081ce090967a4ac
2018-05-07 18:04:43 +00:00
Aaron Schulz
5bfa77f8d9 rdbms: enforce and improve LBFactory/LoadBalancer callback handling
* Handle the case where an onTransaction* callback for one handle
  adds more onTransaction* callbacks to a different handle. Instead
  of supporting only a short chain of such callbacks, try to resolve
  the whole chain by using a loop in LoadBalancer and LBFactory.
* Add sanity checks to enforce the proper call order of LoadBalancer
  transaction methods, such as those that execute callbacks. This is
  the order that LBFactory already uses. Use ROUND_ERROR for problems
  that can ruin the instance state. Such problems require rollback.
* Correct setTrxEndCallbackSuppression() calls in beginMasterChanges()
  that were making tests fail.
* Make Database handle callback suppression for FLUSHING_ALL_PEERS
  instead of making LoadBalancer/LBFactory have to manage it.
* Simplify finalizeMasterChanges() given that suppression does not
  actually effect runOnTransactionPreCommitCallbacks().
* Make dangling callback warning in Database::close work properly.
* Actually use $fname in flushReplicaSnapshots().
* Use DBTransactionError instead of DBExpectedError in some places
  where stages fail.
* Fix failing testGetScopedLock() unit tests so everything passes.

Add more comments to setTransactionListener and onTransactionIdle.

Change-Id: I6a25a6e4e5ba666e0da065a24846cbab7e786c7b
2018-04-30 21:55:25 +00:00
Aaron Schulz
628a3a9b26 rdbms: make sure cpPosIndex cookie is applied to LBFactory in time
Once getMain() was called in setSchemaAliases(), the ChronologyProtector
was initialized and the setRequestInfo() call in Setup.php had no effect.
Only the request values read in LBFactory::__construct() were used, which
reflect $_GET but not cookie values.

Use the $wgDBtype variable to avoid this and add an exception when that
sort of thing happens.

Further defer instantiation of ChronologyProtector so that methods like
ILBFactory::getMainLB() do not trigger construction.

Bug: T192611
Change-Id: I735d3ade5cd12a5d609f4dae19ac88fec4b18b51
2018-04-23 15:44:02 +00:00
Aaron Schulz
e9d42c0e7e rdbms: add $flags argument to ILoadBalancer::getAnyOpenConnection
Make LoadMonitor use this flag for getting a connection.

Change-Id: I32ea9aadc0223c86db5979d6579d781a6af0ff53
2018-04-16 14:17:52 -07:00
Brad Jorsch
78c3b9c21a LoadBalancerTest: Clean up transaction handling for sqlite
We need to make sure a DBO_TRX transaction was started before doing the
CREATE TABLE, because CREATE TABLE itself won't start one and sqlite
breaks if schema changes are done on one handle while another is open.

Also, incidentally, have the handles in these LoadBalancerTests log to
the standard channel. And clean up the auto-rollback of DBO_TRX
transactions to use ->rollback() instead of ->doRollback() plus
incorrect manual setting of trxStatus.

Bug: T191863
Change-Id: Ib422ef89e7eba21281e6ea98def9f98ae762b9fe
2018-04-13 13:42:47 -04:00
Aaron Schulz
40b2e059c0 Reset table sequences and skip some test assertions for sqlite
Various revision storage tests assume the sequences are reset
and fail otherwise.

Also disable some failing tests that are not applicable to sqlite
as well as postgres.

Change-Id: Ibdb034121a44e16bb35059a92baafb1867951ea8
2018-04-13 10:36:08 +00:00
jenkins-bot
6a3aadf097 Merge "rdbms: rename CONN_TRX_AUTO constant to CONN_TRX_AUTOCOMMIT" 2018-04-12 20:38:58 +00:00
Aaron Schulz
f8c2486d15 rdbms: rename CONN_TRX_AUTO constant to CONN_TRX_AUTOCOMMIT
The "AUTO" means AUTOCOMMIT, not "automatic transactions"/DBO_TRX,
which is basically the opposite concept. The new name does not
suffer from that ambiguity.

Keep the old constant as an alias for backwards compatibility.

Also remove LoadBalancer comment about non-existing field

Change-Id: I63beeb061fc9be73f320308e4d6393b58628b8c8
2018-04-12 13:01:52 -07:00
Brad Jorsch
0618227f7f rdbms: Issue a deprecation warning if errors are ignored
I532bc5201 added code to put the Database into an error state on error,
to prevent callers from catching and ignoring exceptions without rolling
back. But to avoid breaking everything relying on the ability to do so,
it didn't set the error state for certain types of errors.

To allow those broken callers to be cleaned up, log a deprecation
warning when we detect that someone has indeed ignored one of these
errors.

Bug: T189999
Change-Id: Ib7aca59639f30959e106fd4f1a1209e28bad2857
2018-04-10 02:06:44 +00:00
Kunal Mehta
b4925e34d0 tests: Enable PHPUnit 4/6 compat layer in some tests that need it
Change-Id: I27a21fa9e97414fae02acbefb28011f0275cba63
2018-04-07 19:31:24 -07:00
jenkins-bot
0bcb82eb7d Merge "rdbms: Remove support for PostgreSQL < 9.2, and improve INSERT IGNORE for 9.5" 2018-04-05 21:33:26 +00:00
Brad Jorsch
cc0473766a rdbms: Remove support for PostgreSQL < 9.2, and improve INSERT IGNORE for 9.5
MediaWiki doesn't support PostgreSQL < 9.2, so drop the support for
older versions.

At the same time, since we're messing with the DatabasePostgres::insert()
code anyway, let's start using ON CONFLICT DO NOTHING for PG >= 9.5.

And since we're doing that, let's do the same for
DatabasePostgres::nativeInsertSelect().

Change-Id: I7bf13c3272917ebafeaff11eb116714a099afdf3
2018-04-05 20:52:46 +00:00
Brad Jorsch
395462b7d5 rdbms: Roll back empty implicit transaction on error
If we're not going to set trxStatus to an error state in this case, we
need to issue a rollback to be sure the database (i.e. PostgreSQL) isn't
still in an error state too.

Bug: T189999
Change-Id: Id6e203b216fff937b6a97d779b36c278e3366409
2018-04-05 14:45:18 -04:00
Aaron Schulz
3975e04cf4 rdbms: make Database query error handling more strict
Handle all errors in query() that might have caused rollback by
putting the Database handle into an error state that can only be
resolved by cancelAtomic() or rollback(). Other queries will be
rejected until then.

This results in more immediate exceptions in some cases where
atomic section mismatch errors would have been thrown, such as a
an error bubbling up from a child atomic section. Most cases were
a try/catch block assumes that only the statement was rolled back
now result in an error and rollback.

Callers using try/catch to handle key conflicts should instead use
SELECT FOR UPDATE to find conflicts beforehand, or use IGNORE, or
the upsert()/replace() methods. The try/catch pattern is unsafe and
no longer allowed, except for some common errors known to just
rollback the statement. Even then, such statements can come from
child atomic sections, so committing would be unsafe. Luckily, in
such cases, there will be a mismatch detected on endAtomic() or a
dangling section detected in close(), resulting in rollback.

Remove caching from DatabaseMyslBase::getServerVariableSettings
in case some SET query changes the values.

Bug: T189999
Change-Id: I532bc5201681a915d0c8aa7a3b1c143b040b142e
2018-04-04 21:26:11 -07:00
Umherirrender
d9fb8bab5e Move phpunit @group from file comment to class comment
Remove @group from non tests

Change-Id: Iae9ee3bc5f539a9b4ded8374006ab2993234450e
2018-03-10 11:48:28 +01:00
addshore
f3df984c79 Introduce IDatabase::buildSubstring
Change-Id: I96f3e0c4920d52f63175cb6767c149f20a8a8cde
2018-03-07 12:32:50 +00:00
Aaron Schulz
c1aa9450ad rdbms: make LoadBalancer::getConnection() ignore CONN_TRX_AUTO when unusable
Change-Id: I1fd13171c3cfbe071e8e398d561281188d998767
2018-03-02 18:40:39 +00:00
Aaron Schulz
ec550d4823 rdbms: remove "m" prefix from Database fields
Done using the PhpStorm refactor->rename tool.

Also move "defaultBigSelects" declaration to DatabaseMysqlBase
as no other classes uses that.

Change-Id: I424a2d9815de3a5d4cca2522f3db23a5efe6b592
2018-02-15 23:29:34 +00:00
jenkins-bot
bed43f5255 Merge "rdbms: avoid "SHOW MASTER/SLAVE STATUS" queries in the GTID case" 2018-02-14 23:37:34 +00:00
Reedy
39f0f919c5 Update suppressWarning()/restoreWarning() calls
Bug: T182273
Change-Id: I9e1b628fe5949ca54258424c2e45b2fb6d491d0f
2018-02-10 08:50:12 +00:00
Aaron Schulz
e59b0556f4 rdbms: make DOMAIN_ANY ignore bogus MySQL DB names in config
This regressed in 14ee3f2, trying to select the server config
"dbname" value as the database on connect. If that config is
bogus, then the connection attempt would fail. Instead, always
pass null to the driver's connection function if the DB domain
doesn't matter.

This affected WMF sites during lag checks, on account of the
"serverTemplate" value in $wgLBFactoryConf always using the local
wiki domain (whether the cluster had such a database or not).

Use strlen() as mysqli sees null and "" as the same for $dbname.

Bug: T186764
Change-Id: I6699d17c0125a08415046211fee7906bbaf2c366
2018-02-09 06:43:24 +00:00
Aaron Schulz
a114bd9f4d rdbms: avoid "SHOW MASTER/SLAVE STATUS" queries in the GTID case
The binlog file/pos where only being used in __toString() for the GTID
case. Make that method use the GTID set instead and avoid querying the
old-fashioned binlog fields all together in that case. The STATUS
queries involve some global lock contention.

Bug: T180918
Change-Id: I18123a702e4f554b87bf5f90017b248062e73049
2018-02-08 09:26:48 -08:00
Aaron Schulz
6237fd11b6 rdbms: make affectedRows() work more consistently
* Update replace()/upsert() to combine the affected row
  count for the non-native case
* Also make replace() atomic in the non-native case,
  similar to how upsert() already works

Change-Id: I6c9bcba54eca6bcf4a93a9b230aaedf7f36aa877
2018-01-30 20:02:07 -08:00
Umherirrender
45da581551 Use ::class to resolve class names in tests
This helps to find renamed or misspelled classes earlier.
Phan will check the class names

Change-Id: Ie541a7baae10ab6f5c13f95ac2ff6598b8f8950c
2018-01-26 22:49:13 +01:00
Aaron Schulz
14ee3f2107 rdbms: specify DB name and table prefix even for the local domain
When LoadBalancer opens new local domain connections, it currently
assumes that the domain specified by the server info array is the
same. For sanity, make sure that the handle is set to the local
domain.

The main LBFactory/LoadBalancer use $wgDBname/$wgDBprefix as the
local domain, corresponding with wfWikiId(). This relation is set
automatically in MWLBFactory. If $wgLBFactoryConf/$wgDBservers is
manually configured in a way breaking this correspondance, then it
is misconfigured.

Fixes made to avoid test failure:
* Make sure LoadBalancer::setDomainPrefix() updates the local
  domain alias member. Also do not bother changing the domain of
  foreign connections.
* Use the right domain ID for the connection array key names in
  LoadBalancer::openForeignConnection().
* Now that JobQueueTest no longer mistakenly uses the non-test
  tables, force it to use the main DB_MASTER handle so that it can
  see the unit test tables even if they are TEMPORARY; such tables
  are tied to the TCP connection, so separate handles see different
  temporary tables.

Change-Id: I56f8b32fe957f984b8c9753e6db3b20abe96b038
2018-01-16 17:06:52 +00:00
Aaron Schulz
05fafcc075 rdbms: add LoadBalancer::getLocalDomainId() method
This returns the default domain without getting a connection

Also avoid assuming that LoadBalancerTest has the same DB handle
as other tests even though it makes its own LB object. That breaks
if temporary tables are used.

Change-Id: I351d42de38b3126222c5a40627a2a12f76a60939
2018-01-13 12:52:59 -08:00
Aaron Schulz
d5aa846d84 Replace cpPosTime cookie/parameter with cpPosIndex
This handles multi-DB transactions properly, instead of causing wait
timeouts in the WaitConditionLoop. It also is more correct in using
a counter instead of relying on wall clocks.

In addition:
* Refactor related code in MediaWiki.php to be comprehensible.
* Always send the cookie even the "remote wiki redirect" case.
* Renamed ChronologyProtector field and constant to avoid any
  confusion of "wait for server X to reach Y" with "wait for Y
  to show up in position store".
* Add an "asOfTime" field to the position keys for debugging.

Bug: T182322
Change-Id: I5c73cd07eaf664f02ba00c38fab9f49b609f4284
2018-01-02 17:00:32 -08:00
jenkins-bot
f70f3f285a Merge "Add @coversNothing in places where @covers does not apply" 2017-12-28 16:39:10 +00:00
Kunal Mehta
92ee198c66 Add @coversNothing in places where @covers does not apply
These tests apply to things that are not relevant to PHP code coverage,
such as testing presence of messages, JSON files, or the PHPUnit tests
themselves.

Using @coversNothing indicates that there is no code here to be covered,
and prevents warnings when using --strict-coverage mode (T152923).

Change-Id: Id89ee2c15a3ce3f10e34b13fb677cd1af75af9e6
2017-12-28 08:53:40 +00:00
Kunal Mehta
9e7e12252a Add @covers tags to database tests
Change-Id: Ic46bb961b41856d390ffe0e3632790c506f5655b
2017-12-28 08:53:23 +00:00
Roan Kattouw
9a6f63cd8c Follow-up e213462f7c: fix typo ("constriant" -> "constraint")
Change-Id: I6e1fd74e387af5a913301bf296fe9f6da0dd1837
2017-12-21 12:59:53 +01:00
daniel
e213462f7c Test for writes being prevented on replica connections.
Bug: T183265
Change-Id: I319efa418cf8a46985f6faa60096559efa15d267
2017-12-21 12:33:39 +01:00
Max Semenik
ee44a10c3d Add a few schemas to SQLite tests
Change-Id: I09f2f98100b7bd74abc468b612dc6e90d95975c7
2017-10-13 19:39:06 +00:00
Umherirrender
f739a8f368 Improve some parameter docs
Add missing @return and @param to function docs and fixed some @param

Change-Id: I810727961057cfdcc274428b239af5975c57468d
2017-09-10 20:32:31 +02:00