Commit graph

145 commits

Author SHA1 Message Date
Umherirrender
88fe512c22 Pass function name to database functions (rdbms/installer)
Change-Id: Ia37d37f2471960c1d9d04fd9bd86224058e88413
2020-06-07 21:06:47 +02:00
Reedy
b3734a0ef4 Fix even more Squiz.Scope.MethodScope.Missing
Change-Id: I0c3f8ce7fddfa6886413cdaf1edc236c4dfff44e
2020-05-17 03:07:58 +01:00
Reedy
40e522747c Fix some includes/libs PSR12.Properties.ConstantVisibility.NotFound
Change-Id: I92e2cbf39d2851d215e8be456e86bb99524dea5f
2020-05-16 02:32:53 +01:00
daniel
4b5984bcca rdbms: don't treat lock() as a write operation
I8ac4bc4d6 caused lock() to be counted as a write operation. Since
acquiring a lock may by design take a long time (e.g. PageEditStash),
this was causing transactions to be flagged as problematic due to the
large amount of time spent in this "write query".

Bug: T251457
Change-Id: Ic54d6c78b43a463c8f6edc6d65baa671a39ee39c
2020-05-01 16:55:25 +00:00
Aaron Schulz
27cf5ace45 rdbms: add IDatabase::QUERY_* flags to obviate isWriteQuery()
This reduces regex overhead and reliance on brittle assumptions.
This will also be useful for complex write queries involving WITH.
Some RDBMS types allow writes with in the WITH aliases themselves,
in addition to the main query itself. Checking raw SQL strings for
such things would get fairly complex.

Change-Id: I8ac4bc4d671abf02f97e82c5daf7b21271b85e5e
2020-04-28 00:49:11 +00:00
Aaron Schulz
cbc700e186 rbms: optimize and rename truncateTable() to truncate()
Allow truncation of multiple tables. This also provides for
a way to avoid risky keywords like CASCADE for Postgres.

For Postgres, use RESTART IDENTITY, which has been supported
since Postgres 8.4.

Avoid TRUNCATE/DELETE queries for empty temp tables, which is
useful for integrations tests that frequently call this method.

Reorganize and tweak the regexes in Database::getTempWrites().
It now recognizes multi-table DROP/TRUNCATE (Postgres-style).

Change-Id: Idd49f118b20ea5a0f7a3e8c00369aabcd45dd44e
2020-04-21 01:26:18 -07:00
Aaron Schulz
303ec64395 rdbms: convert "Exception" try/catch blocks to "Throwable" or "RuntimeException"
Change-Id: I95c204c5c436c3504dcab9e7fe2ae27936ffb590
2020-04-02 01:14:17 +00:00
jenkins-bot
20a0c8ab5a Merge "rdbms: add QUERY_IGNORE_DBO_TRX to duplicateTableStructure() queries" 2020-03-29 16:42:34 +00:00
Aaron Schulz
d42ad1e215 rdbms: add QUERY_IGNORE_DBO_TRX to duplicateTableStructure() queries
Make related DatabaseSqlite::listTables() method directly use query()
rather than high-level wrapper.

Change-Id: I253f83091fb62fd0a449ac78d8846fb69bb808f6
2020-03-27 01:40:24 +00:00
Brad Jorsch
1ba4d0ccd4 rdbms: Don't silence errors in DatabaseMysqlBase::serverIsReadOnly()
It's highly unlikely that that query would ever error, but if it does
(and apparently it does sometimes somehow) we need to either handle the
error or let it be raised.

Since there doesn't seem to be any particularly sane thing to assume if
there is an error, let's go with "let it be raised".

Bug: T247865
Change-Id: I6c0e08df90eb46953ba5eb6b5a3e8c6f52929564
2020-03-25 15:09:06 -04:00
Aaron Schulz
e1a8c4e2a0 rdbms: add IMaintainableDatabase::truncateTable()
Use it in MediaWikiIntegrationTestCase for resetting tables.

Also create Database::resetSequencesForTable() helper method from
the resetSequenceForTable() methods in the SQLite/Postgres classes.

Change-Id: I20945e20590e69340b1ce75f6bb2f6972375b00c
2020-03-25 01:36:06 +00:00
Aaron Schulz
13b11a946e rdbms: reduce duplication in Database via helper methods
Add several new internal methods to help with wrangling
the various formats that rows, conditions, options, and
unique key lists can come in. Remove now unused method
isMultiRowArray().

Add various sanity checks and logging for parameters to
upsert(), replace(), insert(), and insertSelect().

Move DatabasePostgresTest to the integration/ directory.

Change-Id: If5988a6f0816e8da2cbf2fd612e1a3e3a2e9c52f
2020-03-10 22:26:04 +00:00
jenkins-bot
44354f45eb Merge "rdbms: inject replLogger into Database and consolidate duplicated logging" 2020-03-04 21:29:23 +00:00
Aaron Schulz
ccebc2317b rdbms: improve IDatabase method documentation and parameter names
Change-Id: I87c0c6e418fe19bd837b38ebdfb967466f967fca
2020-03-02 22:59:12 +00:00
Aaron Schulz
6c5d937adb rdbms: inject replLogger into Database and consolidate duplicated logging
Bug: T235244
Change-Id: I9397f6f74f703a395ef1be4713702247060d8bd4
2020-02-23 00:33:33 +00:00
James D. Forrester
0958a0bce4 Coding style: Auto-fix MediaWiki.Usage.IsNull.IsNull
Change-Id: I90cfe8366c0245c9c67e598d17800684897a4e27
2020-01-10 14:17:13 -08:00
James D. Forrester
4f2d1efdda Coding style: Auto-fix MediaWiki.Classes.UnsortedUseStatements.UnsortedUse
Change-Id: I94a0ae83c65e8ee419bbd1ae1e86ab21ed4d8210
2020-01-10 09:32:25 -08:00
sbassett
2e11b14455 rdbms: Log debug message traces as 'exception.trace' instead of 'trace'
Code cleanup and hardening (see also: T234014) of Database-related
lib code in MediaWiki core.

Bug: T233342
Change-Id: I3c968f4f5300374253dc80d99596cac50fbeb59e
2019-12-04 21:45:28 +00:00
jenkins-bot
3fb1bd2c72 Merge "Have Database::addQuotes() pass through bare integers without quoting" 2019-11-18 17:42:12 +00:00
Tim Starling
673d496f2d Have Database::addQuotes() pass through bare integers without quoting
Quotes started being added to integers in r4984 (August 2004). Before
that, is_numeric() was used to determine whether to add quotes, so
quotes were omitted from numeric strings, which is obviously wrong.

The idea here is to use the type of the variable to hint to the database
as to whether quotes are needed. The results are somewhat inconsistent,
since some callers do not convert numeric strings obtained from user
input to integers. That makes it a more conservative change. Callers can
opt out of unquoted integers by casting them to string.

The reason for doing this is that quoting integers turns out to be not
as harmless as originally assumed. We found a case of it confusing the
MariaDB query planner, causing inappropriate indexes to be used.

I also made addQuotes() consistently return a string, instead of
returning an integer for boolean values. This was already the case for
MySQL, but it seems like a good idea everywhere.

Bug: T238378
Change-Id: I70473280f542ee5ecd79e187f580807410fbd548
2019-11-18 11:40:28 +11:00
Thiemo Kreuz
e6615256c2 rdbms: Fix DatabaseMysqlBase::streamStatementEnd() possibly failing
If a string starts with "DELIMITER" but the word is *not* followed by
a space, the code will set $this->delimiter to null, possibly resulting
in all kinds of hard to track errors.

Even more problematic: the preg_match was *not* case-insensitive, but the
condition was. Which means that all non-uppercase "delimiter …" would
result in the same error.

I'm not sure if it's worth keeping the additional string comparison for
performance reasons. Probably not. That comparison is slow as well, and
preg_match is surprisingly fast (when the pattern is properly written,
which it is).

Change-Id: I33944b7a2410f77e67ce7450af0359a88d39f1aa
2019-11-08 17:25:08 +01:00
jenkins-bot
c3c45ff689 Merge "Fix new phan errors, part 6" 2019-10-20 18:05:18 +00:00
Daimona Eaytoy
114ee6e412 Fix new phan errors, part 6
Bug: T231636
Change-Id: I1870b6cbeb31e54fde5e675fec51446b330e06c5
2019-10-20 17:53:48 +00:00
Aaron Schulz
fb621c26a3 rdbms: various cleanups to LoadBalancer::reallyOpenConnection()
Move the DBO_TRX init logic out of Database::__construct() and into
LoadBalancer since the later already handles setting and clearing this
flag based on transaction rounds starting and ending.

Add 'lazyMasterHandle', 'topologyRole', and 'topologicalMaster' parameters
to Database::factory() and inject them via LoadBalancer all at once in order
to avoid worrying about call order. Move some type casting code to
Database::__construct().

Add IDatabase::getTopologyRole()/getTopologicalMaster().

Use constants for getLBInfo()/setLBInfo() for better usage tracking and
typo resistance.

Change-Id: I437ce434326601e6ba36d9aedc55db396dfe4452
2019-10-11 11:35:02 -07:00
Aaron Schulz
dd5cb85863 rdbms: make DatabaseMysqlBase::masterPosWait() logging clearer about GTID filtering
Bug: T224422
Change-Id: I52aa27d79588d7dc291530ed33484903b8244134
2019-10-10 17:06:03 -07:00
Aaron Schulz
8f20122c18 rdbms: fix active GTID filtering in DatabaseMysqlBase
In masterPosWait(), only $pos will have the known active domain/server set
since it usually comes from getMasterPos(). However, the reference position,
from getReplicaDB(), does not have the active domains set since querying
gtid_domain_id on the replica would be incorrect and getting a connection
to the master could be expensive.

Remove obsolete hacks for jobs that used to store master positions.

Also, use the regular Database::query() method for stylistic consistency.

Bug: T224422
Change-Id: I41bbb9f337e46451aa17788dbd446db4a213a5a7
2019-09-25 11:59:05 +00:00
Aaron Schulz
982d493a4c rdbms: migrate DatabaseMysqlBase::getServerVersion() to using the local server cache
Change-Id: If667f761b2173226ccf1129ec864d1ce9729024a
2019-09-03 20:24:56 -07:00
Aaron Schulz
c06bda1bed rdbms: refactor caching in LoadBalancer::getReadOnlyReason()
Avoid nesting of the same getWithSetCallback() cache updates.
Also favor accuracy over initial cache use for the case where
there is already a master connection. Add missing "lockTSE"
flag to protect against stampedes updating stale values.

Change serverIsReadOnly() to use SELECT in mysql instead of
SHOW to avoid internal temporary tables.

Bug: T227838
Change-Id: I2b0d680c9c3bdc7aaa1d1e1d6beb2dd203a815f1
2019-08-25 21:31:28 +00:00
Aaron Schulz
cbc8451d71 rdbms: remove IDatabase::clearFlag() calls made redundant by QUERY_IGNORE_DBO_TRX
Change-Id: I493c63f94c813ad71dc2eb8eaf9119a1f11d62cb
2019-08-21 19:10:25 +00:00
Aaron Schulz
3cdf794c95 rdbms: remove HIGH_PRIORITY/LOW_PRIORITY SQL references from IDatabase
These should not be used even with MySQL as they do not help concurrency

Change-Id: I5385fcbe65e676b184268286bedd5c2299b447d4
2019-08-07 15:04:53 -07:00
Aaron Schulz
023c73f612 rdbms: normalize Database open() code and error handling
Mainly:
* Use oci_new_connect() for Oracle to avoid broken connection reuse
  similar to the PGSQL_CONNECT_FORCE_NEW flag in DatabasePostgres
* Set 'client_min_messages' unconditionally for PostgreSQL
* Factor out Database::getConnectExceptionAndLog() helper method
* Use the same style of query() calls in DatabaseOracle::open() as
  the other subclasses
* Make sure the Database driver handle field is null on failure
  instead of false for sanity

Also:
* Disallow changing of Database handle DBO_* flags after construction
  where it does not make sense to change them
* Do not mention DBO_* flags meant for non-config use in $wgDBservers
* Ignore DBO_PERSISTENT for SQLite if DBO_TRX is also set for sanity
* Remove $wgDBOracleDRCP variable to discourage careless automatic
  setting of DBO_PERSISTENT that breaks LoadBalancer assumptions

Change-Id: Iea948f7f872294ea8fc5d897fc10c9d29b7141d5
2019-07-26 15:24:28 +01:00
Aaron Schulz
d322031d52 rdbms: switch to AtEast warning suppression in Database classes
Change-Id: Ia32f1ba048a540438f78b11a1e94f80acfc7bf50
2019-07-13 01:49:05 +00:00
Aaron Schulz
c351a9cab0 rdbms: cleanup some Database error message wording for consistency
Change-Id: I7b338e6e856c62ecaab2ef97f76431c2220b430d
2019-07-11 21:37:54 +00:00
Aaron Schulz
a830c14d0b rdbms: make implement IResultWrapper directly instead of via inheritence
Change-Id: If1b15c0c21d0ee336025fb99f47fc19ddf1d5435
2019-07-04 13:42:53 +00:00
Aaron Schulz
826dcd87b0 rdbms: add SHOW to isTransactableQuery() and add QUERY_IGNORE_DBO_TRX uses
This assures that less pointless transactions are started

Change-Id: I61a52e989e1c9c20c58b1da773f5209ba283a83e
2019-06-28 18:49:12 -07:00
Aaron Schulz
7911da9c6f rdbms: remove $opened field from Database for simplicity
This avoids having two similar fields that have to stay
in sync. Clean up the related error handling for connections.
If a connection handle is unusable, like when essential SET
queries fail, then destroy it.

Also:
* Avoid use of transactions in DatabasePostgres::determineCoreSchema.
* Make sure all subclasses log on connection failure.
* Add schema sanity checks to mysql/sqlite classes.
* Add IDatabase::QUERY_NO_RETRY flag to simplify reasoning about
  queries that already run on open() to begin with.
* Remove unused return value of Database::open.
* Remove deprecated Database::reportConnectionError method.

Change-Id: I97beba7ead1523085bda8784234d00c69ef1accc
2019-06-27 18:29:12 +01:00
Aaron Schulz
b9a67d4710 rdbms: deprecate unused ILoadBalancer::safeGetLag method
Change-Id: Ib3bc2862548271613da30ad1be836d28a82e6cc9
2019-06-19 17:16:29 +00:00
Umherirrender
e85c138312 rdbms: Fix return type of DatabaseMysqlBase::mysqlFetchArray
Change-Id: I7797ae79e8b4c1a88a4f1da342ef4a4f5a78ed74
2019-06-18 20:21:42 +00:00
Aaron Schulz
f5880b7dc7 rdbms: reorganize Database fields and constants
Move the constants to the bottom and make more of them private.
Place the configuration fields at the top of the list.
Also, move some related fields closer to each other.

In addition:
* Rename the named lock tracking variable to start with the
  prefix "session" for consistency.
* Remove unused $preparedArgs field.
* Rename $sessionVars and $rttEstimate fields.
* Use short field documentation syntax.
* Make transaction callback fields private.

Change-Id: I7d78be6744723f4d7bb32a75154564ee04eca0f6
2019-06-13 17:39:24 +00:00
Aaron Schulz
2866c9b7d4 rdbms: add Database::executeQuery() method for internal use
This shares reconnection and retry logic but lacks some of the
restrictions applied to queries that go through the public query()
interface.

Use this in a few places such as doSelectDomain() for mysql/mssql.

Bug: T212284
Change-Id: Ie7341a0e6c4149fc375cc357877486efe9e56eb9
2019-06-11 14:00:41 +00:00
Umherirrender
348a784f48 Adjust type hints in database related classes
Change from ResultWrapper to IResultWrapper
Change from mysqli_result to resource
Changed mixed to return hint of interface
Document that fieldInfo returns bool

Change-Id: I5572fd41e0e11a2bc2eb116d0c82327499ecc518
2019-06-05 19:10:13 +02:00
Aaron Schulz
1a6aad9929 rdbms: make $wgSQLMode work as documented when it is NULL
NULL means that the SET query should not be sent.
This was broken since 5bc9b990ac.

Change-Id: I148b1153ef6ecca99c56e4f63247820a766ae779
2019-04-01 14:52:48 -07:00
jenkins-bot
1a62e51a00 Merge "rdbms: treat cloned temporary tables as "effective write" targets" 2019-03-26 22:02:10 +00:00
Aaron Schulz
108fd8b18c rdbms: treat cloned temporary tables as "effective write" targets
Make IDatabase::lastDoneWrites() reflect creation and changes to
the cloned temporary unit test tables but not other temporary tables.
This effects the LB method hasOrMadeRecentMasterChanges(). Other tables
are assumpted to really just be there for temporary calculations rather
acting as test-only ephemeral versions of permanent tables. Treating
writes to the "fake permanent" temp tables more like real permanent
tables means that the tests better align with production.

At the moment, temporary tables still have to use DB_MASTER, given
the assertIsWritableMaster() check in query(). This restriction
can be lifted at some point, when RDBMs compatibility is robust.

Bug: T218388
Change-Id: I4c0d629da254ac2aaf31aae35bd2efc7bc064ac6
2019-03-26 14:24:42 -07:00
Aaron Schulz
321640b117 rdbms: use a direct "USE" query for doSelectDomain() for mysql
This should give better error messages on failure.

Bug: T212284
Change-Id: I55260c6e3db1770f01e3d6a6a363b917a57265be
2019-03-26 18:50:28 +00:00
jenkins-bot
3c3948a6f2 Merge "rdbms: update wasQueryTimeout() for DatabaseMysqlBase" 2019-03-22 00:41:00 +00:00
Aaron Schulz
c6c6325100 rdbms: update wasQueryTimeout() for DatabaseMysqlBase
Change-Id: I533d68972c758a5c8bb251cd838b8802799f0318
2019-03-22 00:24:57 +00:00
Aaron Schulz
3ef6a1d94c rdbms: add 1062 error code to DatabaseMysqlBase
See https://dev.mysql.com/doc/refman/5.7/en/server-error-reference.html

Change-Id: Id4960a5693332e6291ddcb5564bf6f8177a90c3d
2019-03-21 17:18:59 -07:00
Aaron Schulz
e3427b87ca rdbms: add bad mysql table/column codes to wasKnownStatementRollbackError()
Change-Id: I826681ae7582b6f8af09b1d5ed08378532af2556
2019-03-18 20:22:59 -07:00
Aaron Schulz
f41a0837a9 rdbms: clarify $uniqueIndexes argument to replace()/upsert()
Also make upsert() match replace() for consistency.

Change-Id: I208f3ab810a61c6949ac0050436767675f99a60b
2019-03-12 20:09:21 -07:00