Commit graph

79 commits

Author SHA1 Message Date
Aaron Schulz
5358c41e86 rdbms: use Database::getDomainId for transaction logging calls
Change-Id: I360ca633b145dc8e510bb00b542ac44933283943
2018-08-15 01:29:39 -07:00
jenkins-bot
216865344b Merge "rdbms: add IDatabase::lockForUpdate() convenience method" 2018-07-11 19:52:31 +00:00
Aaron Schulz
9eff263e8e rdbms: add IDatabase::lockForUpdate() convenience method
Change-Id: I238fd96407e1122e90058e2c4acf743044a267ec
2018-07-10 20:09:01 +01:00
Aaron Schulz
86dd3b0ac0 Avoid deprecated IDatabase::getWikiId() reference
Change-Id: I26991079b1630335c8a6e907554760fc85c1bad6
2018-07-07 22:55:15 +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
Bartosz Dziewoński
03583f7a91 Use PHP 7 "\u{NNNN}" Unicode codepoint escapes in string literals (part 2)
This is a follow-up to Idc3dee3a7fb5ebfaef395754d8859b18f1f8769a
containing some less trivial changes.

Change-Id: Ia7af2c1d000307d43278cde4a246df413d4ef263
2018-06-04 16:40:48 +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
jenkins-bot
b6e8e6b832 Merge "rdbms: make runOnTransactionIdleCallbacks() reset DBO_TRX on exceptions" 2018-05-30 21:47:27 +00:00
Aaron Schulz
0b5ed025e9 rdbms: do not silently rollback empty transactions on error
Since there might be important view snapshots, temp tables, or effects
from SET statements or the like, go into TRX_ERROR state for "possible
transaction level errors" even if no recognized writes took place and
the transaction was not explicit.

Change-Id: I32c34bc28b845e343d0167a220412824838eaed8
2018-05-30 03:10:02 +00:00
Aaron Schulz
8880a25112 rdbms: make runOnTransactionIdleCallbacks() reset DBO_TRX on exceptions
Change-Id: Ibbb2a3ebf9dd970772ee704aa643a3843f20a3b5
2018-05-25 23:40:47 +00: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
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
c8085ad43f rdbms: make IDatabase::onTransaction* methods pass the DB handle for convenience
Change-Id: Ia45a26830d62326b103593268fbf34c907783c90
2018-04-24 16:45:11 -07:00
jenkins-bot
984381d6d9 Merge "rdbms: make select() warn when FOR UPDATE is used with aggregation" 2018-04-23 20:01:13 +00:00
Aaron Schulz
b992b3aea5 rdbms: make select() warn when FOR UPDATE is used with aggregation
Using FOR UPDATE or LOCK IN SHARE MODE with aggregation leads to
query errors with PostgreSQL.

Bug: T160910
Change-Id: Iaed964e7e59468365cbc62cb4bfd3ad44b898452
2018-04-20 03:42:26 +00:00
Aaron Schulz
20777d7399 rdbms: make cancelAtomic() handle callbacks and work with DBO_TRX
Make transaction callbacks aware of cancelled sections. If the
statements of a section are reverted via cancelAtomic(), then the
dependant callbacks are now cancelled as well. Any callbacks for
onTransactionResolution(), which does not depend on COMMIT, will
see the triggering event as a ROLLBACK, since the unit of work it
was part of was rolled back.

Also fix the handling of topmost atomic sections with DBO_TRX.
These still need their own savepoint to make cancelAtomic() work.

Follow-up to 52aeaa7a5.

Change-Id: If4d455c98155283797678cfb9df31d5317dd91a2
2018-04-19 12:43:01 -07: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
jenkins-bot
296fe3b900 Merge "rdbms: ignore inactive mysql GTIDs in replication position methods" 2018-04-12 01:03:15 +00:00
jenkins-bot
2d030f4576 Merge "rdbms: allow cancelation of dangling nested atomic sections" 2018-04-11 19:48:00 +00:00
Aaron Schulz
f9d10f9e03 rdbms: fix transaction flushing in Database::close
Use the right IDatabase constants for the $flush parameter to
the commit() and rollback() calls.

This fixes a regression from 3975e04cf4.

Also validate the mode/flush parameters to begin() and commit().

Bug: T191916
Change-Id: I0992f9a87f2add303ed309efcc1adb781baecfdc
2018-04-10 22:31:31 -07:00
Aaron Schulz
477b835945 rdbms: allow cancelation of dangling nested atomic sections
* Make startAtomic() return a token that can be used with cancelAtomic()
  cancel any nested atomic sections that have not yet been ended.
* Make doAtomicSection() clear dangling nested sections by default.
* Also give doAtomicSection() a $cancelable parameter, having the
  same default as startAtomic().

Change-Id: I75fa234cb1dcfef17dc9a973a3b02d2607efa98e
2018-04-10 16:34:31 -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
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
jenkins-bot
671e5b4d81 Merge "rdbms: make Database query error handling more strict" 2018-04-05 15:29:20 +00:00
Aaron Schulz
315ffb840b rdbms: ignore inactive mysql GTIDs in replication position methods
If it is known that master writes will use GTIDs with a certain
domain and server ID, ignore other ones on masterPosWait().

This restores ceb7d61ee except it uses the same server variables
and MySQLMasterPos preserves the active server/domain information
across serialization.

Change-Id: I1a4f143adcbec642966d7d1a55edb0f414a7f0c4
2018-04-04 21:58:03 -07: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
jenkins-bot
6c169ee1fd Merge "rdbms: clean up DBO_TRX behavior for onTransaction* callbacks" 2018-04-04 16:18:14 +00:00
Aaron Schulz
d4c31cf841 rdbms: clean up DBO_TRX behavior for onTransaction* callbacks
* Make onTransactionIdle() wait until any transaction round
  is gone, even if there is no SQL transaction active. This
  is what onTransactionPreCommitOrIdle() already does.
* Decouple "transaction round mode" (DBO_TRX) from whether a
  round is active via a 'trxRoundId' LB info field. If rounds
  are enabled, but not is started, then the transaction state
  should be interpreted as "idle".
* Improve related documentation.
* Add more related unit tests.

Change-Id: I3ab18f577ec0375897fcb63f18f4ee2deeb436e9
2018-04-03 23:16:45 -07:00
Aaron Schulz
9ce9f5c4e4 Revert "rdbms: make getMasterPos() ignore GTIDs outside of gtid_domain_id"
This had a noticeable increase in LoadBalancer::doWait timeouts.

This reverts commit ceb7d61ee7.

Change-Id: I7004d55a05c20f646f70d778d7b6496123e270a4
2018-04-02 14:02:47 -07:00
Aaron Schulz
ceb7d61ee7 rdbms: make getMasterPos() ignore GTIDs outside of gtid_domain_id
* Filter out GTIDs with a domain that is not the one binlog
  events would be written to if the Database handle was given
  write queries. Likewise for the MariaDB server_id component.
* Also improve MySQL GTID support to better match that of MariaDB.
  This covers position retrieval, replication waiting, and ranges
  in GTIDs (which are almost always present).
* Make some MySQLMasterPos variables private by making use of
  accesors instead.
* Store the gtids array keyed by domain ID for convenience.
* Clean up dynamic call to static method.

Change-Id: Ic6ab517bc8f200c968ff892ade69ad1b9394ab21
2018-03-22 23:53:05 +00:00
Brad Jorsch
3365e83d96 rdbms: Add ATOMIC_CANCELABLE flag for micro-optimization
Aaron is concerned about the extra time added to atomic sections within
an outer transaction if we do a SAVEPOINT and RELEASE. He wants a flag
so callers have to specifically opt-in to use of savepoints.

Change-Id: I64cf5033ced464863d28dd49d9173856a9c1e1c0
2018-03-22 07:20:54 +00:00
Brad Jorsch
52aeaa7a5f rdbms: Add IDatabase::cancelAtomic()
Atomic sections are currently useful if you want to wrap some SQL
statements in a transaction when you might be called from inside someone
else's transaction, and you expect the caller to roll back everything if
you fail.

But there are some cases where you want to allow the caller to recover
from errors, in which case you need to roll back just the atomic
section. Savepoints are supported by all our databases and can be used
for this purpose, so let's do so.

Bug: T188660
Change-Id: Iee548619df89fd7fbd581b01106b8b41d3df71cc
2018-03-22 05:57:42 +00:00
jenkins-bot
6c1cd929cb Merge "rdbms: clean up DBO_TRX behavior for onTransactionPreCommitOrIdle()" 2018-03-22 01:07:06 +00:00
Aaron Schulz
b0ee0a8d9f rdbms: clean up DBO_TRX behavior for onTransactionPreCommitOrIdle()
* Make sure cancelled onTransactionPreCommitOrIdle() callbacks do not
  run if a transaction round is rolled back and then a second round is
  committed. LoadBalancer::rollbackMasterChanges() now always calls
  rollback(), which in turn always cleans up such callbacks.
* Remove error logging for rollback() calls when trxLevel = 0; this is
  harmless and is sometimes hard to avoid in error handling anyway.
* Add more related unit tests.

Change-Id: I6bdefe8bf8b6630fc252b5bbafe4808758ba1684
2018-03-20 01:11:24 +00:00
Aaron Schulz
d395dfb039 rdbms: make selectRowCount() use $var argument to exclude NULLs
If the $var argument is provided, then it will make the resulting
count exclude rows where the value for that column is NULL.

Also add buildSelectSubquery() method and Subquery
wrapper class for use with select() for calculated tables.

Change-Id: I549d629af99afdf370602de095f7fba6d1546c37
2018-03-18 01:34:33 +00:00
jenkins-bot
ebf1570fd1 Merge "rdbms: allow construction of Database objects without connecting" 2018-03-14 09:57:18 +00:00
Aaron Schulz
4ccb228bde rdbms: inject the mysql index name aliases into Database
Also added LBFactory::setTableAlias() for consistency with this

Change-Id: Ie49003ff8fd5b99f75db9fae8fe0a184444254d4
2018-03-12 18:51:53 +00:00
Brad Jorsch
83731192b2 Remove useless use
A use declaration for a non-namespaced class in a non-namespaced context
causes a PHP warning.

Bug: T189302
Change-Id: I023e64c8194dd03cc3a1098e2d60c73f99bb02e3
2018-03-09 14:11:36 -05:00
Aaron Schulz
434d5a6321 rdbms: allow construction of Database objects without connecting
* Database::factory() supports a $connect parameter, that defaults
  to NEW_CONNECTED (current behavior) but can also be NEW_UNCONNECTED.
* Add tests asserting the type of various instances returned from
  Database::factory().
* Clean up sqlite "conn" field handling to handle cases of it
  not being set, just as other classes do.
* Add some comments about the return type of doQuery().

Change-Id: Ic0837cfdb35326c2045133d664abd29043d48c03
2018-03-08 19:47:35 -08:00
Timo Tijhof
a211db0f73 rdbms: Restore test for Database::setFlag()
Follows-up b4eb1feed0, which inadvertendly replaced the setFlag()
test with the clearFlag() test.

Also move the test to the DatabaseTest.php file given it's only
executing and covering base class.

Change-Id: I2f4ed6c4eeba845eb67013e1ab7d2b2bde863119
2018-03-08 04:32:21 +00:00
Aaron Schulz
b4eb1feed0 Remove FakeDatabaseMysqlBase test class
Improve some flag tests that did not seem to test much

Change-Id: Iecfc877645cc66cb696beb2b314a6d149745a530
2018-03-07 11:45:04 -08:00
addshore
0526f2d671 Introduce IDatabase::buildIntegerCast
Change-Id: Ib24856d1ebe017ff07ae497972c764b4a3f3c7df
2018-03-07 13:00:18 +00:00
addshore
f3df984c79 Introduce IDatabase::buildSubstring
Change-Id: I96f3e0c4920d52f63175cb6767c149f20a8a8cde
2018-03-07 12:32:50 +00:00
jenkins-bot
a4a25aeb26 Merge "rdbms: add missing hint check DatabaseMysqlBase::isInsertSelectSafe" 2018-03-02 19:10:28 +00:00
daniel
fa9f1aca87 rdbms: in Database::selectSQLText, do not treat $conds = "0" as no condition
This fixes an issue that arises because empty( "0" ) is true in PHP.

The new behavior rejects any conditions that are not strings or arrays,
and lets $conds = "0" be passed to the databases as WHERE 0.

Some databases may reject this as invalid syntax, which is the expected
behavior here, instead of silently ignoring the 0, causing no condition to
be applied to the query.

Bug: T188314
Change-Id: I5bc4d7f41221a886c85e54d9da67c4c095a7d9ce
2018-03-02 10:25:44 +00:00
Aaron Schulz
3b9e6bec3e rdbms: add missing hint check DatabaseMysqlBase::isInsertSelectSafe
This was lost when a bunch of other logic was split off in 671368a59e

Change-Id: I3d3f744f8fce007ecf88cbd2c9f99918b06f0573
2018-03-01 21:03:54 -08:00
Brad Jorsch
99b65649c0 rdbms: allow callers to hint that native insertSelect() is safe
An INSERT SELECT in MySQL/MariaDB is unsafe for replication if a column
is getting values from auto-increment, statement-based replication is in
use, and the default innodb_autoinc_lock_mode is set.

I9173f655 added checks to force non-native insertSelect for the
statement-based replication and innodb_autoinc_lock_mode != 2 case, but
determining whether a column is getting values from auto-increment is
too hard to do automatically there.

Instead, let's add a flag to let the caller hint that the query isn't
getting any auto-increment values. And use it in MysqlUpdater when
appropriate.

Bug: T160993
Change-Id: If70450a64aa3bcbf763c62838bb21306d124ae3d
2018-02-28 13:58:37 -05:00
Brad Jorsch
aefb143a8e Database: Add batching to non-native insertSelect()
It would be easy for a call to nonNativeInsertSelect() to generate an
INSERT that's too big for the database to actually process. Add batching
to try to avoid that.

Bug: T160993
Change-Id: I1de994208d95926f0d75c0d7cab7b5fe1dd565c3
2018-02-28 13:58:37 -05:00