Commit Graph

605 Commits

Author SHA1 Message Date
dave 0b6990402f make tables under innodb 2019-04-14 16:56:23 -07:00
Jason Madden f211a2b6e0
Attempt to fix Python 2.7 false test failures. 2019-01-07 08:38:49 -06:00
Jason Madden f80e53aa2d
Avoid deleting attributes of DB driver modules.
Fixes #206.
2019-01-07 08:20:53 -06:00
Jason Madden bed12e8416
Fix pylint errors 2018-02-02 08:42:05 -06:00
Jason Madden db12477bc3
Update to Pylint 1.7
Fixes #181

Mostly a few changes in pragmas. There are also a few actual code
changes:

- remove reduntant `else return` after `if return`
- Change some `x = foo and bar or baz` into equivalent `bar if foo
  else baz` forms.
2017-06-22 10:27:27 -05:00
Jason Madden 3860375815
Use a better query to delete blob chunks for HF MySQL
Fixes #175.

Also pins pylint because 1.7.0 has a number of (good!) new warnings.
2017-04-14 10:16:52 -05:00
Jason Madden 622459d2e9
Test compatibility with ZODB 5.2.2+
Because it did break a test, as mentioned in
https://github.com/zopefoundation/ZODB/pull/156
2017-04-11 17:05:01 -05:00
Jason Madden 2babc54c43
Implement get_object_count exactly.
Fixes #178.

Note this changes the constructor signature for the *Stats classes to
take the keep_history flag.
2017-04-11 12:20:42 -05:00
Jason Madden 3b65f778e6
Test on ZODB 4.4
Fixes #169.

We need this version for IMultiCommitStorage and the registerDB fix in
ConflictResolvingStorage. Since these versions run on Python 2.7.8,
there's no motivation for trying to go back farther.
2017-04-11 09:27:46 -05:00
Jason Madden 6792f7777d
Comment on possibly related errors in MySQLLocker. 2017-03-20 09:18:46 -05:00
Jason Madden 64a7515de9
Workaround TypeError in MySQLOIDAllocator
The caller should generally retry.

Fixes #173.
2017-03-20 08:55:04 -05:00
Jason Madden 02e1369159
Document cx_Oracle version constraints. Fixes #172. [skip ci] 2017-03-10 13:18:57 -06:00
Jason Madden dca01ab917
pylint/pylibmc spurious errors on new version 2017-03-08 12:15:32 -06:00
Jason Madden 4d3b8124a5
Oracle: Fix two queries that were broken in 2.1a1. 2017-03-08 12:03:48 -06:00
Jason Madden a1f3b236c4 Merge pull request #168 from zodb/issue166
Wrap lines at 100. Fixes #166.
2017-02-09 17:56:39 -06:00
Jim Fulton f57ad7eaa4 Added interface declaration and explanation for why afterCompletion only rolls back the load connection. 2017-02-09 11:43:30 -05:00
Jason Madden b1ea762bf4
Wrap lines at 100. Fixes #166. 2017-02-09 09:59:38 -06:00
Jim Fulton 50a916e685 Implemented the storage ``afterCompletion`` method, which allows
RelStorage storages to be notified of transaction endings for
transactions that don't call the two-phase commit API.  This allows
resources to be used more efficiently because it prevents RDBMS
transactions from being held open.

Fixes: https://github.com/zodb/relstorage/issues/147

(At least for ZODB 5.2.)
2017-02-08 14:46:26 -05:00
Jason Madden ac9c52f237
Use InnoDB temp tables
And truncate them.

For most things this seems to speed up writes by around 10% or more due
to the way the temp tables are allocated.

Tested on both 5.5 and 5.7.

I think the dropping was an attempt to make the tables statement-level
replication compatible, but since they weren't transactianal I don't
think that worked. They were also variable sized so I don't think there
were any speed benefits. It also didn't implicitly end the transaction,
but that's not a concern where this is called.

Here's a complete set of benchmarks against 5.7, comparing zodbshootout
with -c2 and -c6, -n 1000 and '-n 100 -s 256 --test-reps 200'. This
compares 2.0.0 with current master and this change, in that order.

** c=2,s=256 **                2.0.0   master   InnoDB
"Transaction",               mysql_hf
"Add 100 Objects",               8883     9199    10157
"Update 100 Objects",            9380     9169    10318

** c=6,s=256 **                 2.0.0    master   InnoDB
"Transaction",               mysql_hf
"Add 100 Objects",               ----     14913   15524
"Update 100 Objects",            ----     14914   15077

** c=6,s=128 **                 2.0.0    master   InnoDB
"Transaction",                mysql_hf
"Add 1000 Objects",              29815    31704    38506
"Update 1000 Objects",           28978    29030    29137

In all cases, InnoDB temp tables outperform, in some cases
substantially.

An earlier set of benchmarks taken against 5.5 (but prior to a rebase on
master, so not easily replicated). The absolute value difference in
numbers versus above is that these were taken with Py 3.4 while above
was py 2.7.

zodbshootout -c 2 shootout.conf -n 100 --test-reps 200 -r 1 -s 256

Before

** concurrency=2 **
"Transaction",               mysql_hf
"Add 100 Objects",               6493
"Update 100 Objects",            9636
"Read 100 Warm Objects",         9797
"Read 100 Cold Objects",         9336
"Read 100 Hot Objects",         37407
"Read 100 Steamin' Objects",   921761

** concurrency=6 **
"Transaction",               mysql_hf
"Add 100 Objects",              10574
"Update 100 Objects",           15492
"Read 100 Warm Objects",        19290
"Read 100 Cold Objects",        17051
"Read 100 Hot Objects",         72304
"Read 100 Steamin' Objects",  1590488

After

** concurrency=2 **
"Transaction",               mysql_hf
"Add 100 Objects",               7079
"Update 100 Objects",            9782
"Read 100 Warm Objects",         8726
"Read 100 Cold Objects",         9834
"Read 100 Hot Objects",         40004
"Read 100 Steamin' Objects",   937232

c=6
** concurrency=6 **
"Transaction",               mysql_hf
"Add 100 Objects",              10612
"Update 100 Objects",           15789
"Read 100 Warm Objects",        17501
"Read 100 Cold Objects",        16556
"Read 100 Hot Objects",         71868
"Read 100 Steamin' Objects",  1549534

zodbshootout -c 2 shootout.conf -n 100 --test-reps 200 -r 1 -s 96

** concurrency=2 **
"Transaction",               mysql_hf
"Add 100 Objects",              15547
"Update 100 Objects",           14337
"Read 100 Warm Objects",        12357
"Read 100 Cold Objects",        13686
"Read 100 Hot Objects",         54559
"Read 100 Steamin' Objects",   945789

"Transaction",               mysql_hf
"Add 100 Objects",              16968
"Update 100 Objects",           16184
"Read 100 Warm Objects",        13430
"Read 100 Cold Objects",        13557
"Read 100 Hot Objects",         54625
"Read 100 Steamin' Objects",   966802
2017-01-30 14:52:35 -06:00
Jason Madden cf2dad6975
Skip two tests on appveyor
They use threads and or time.time/sleep. Windows/Appveyor is flaky when
it comes to these things (see gevent) so the tests can sometimes
randomly fail.

This dates back to some of the earliest windows builds.
2017-01-29 09:38:15 -06:00
Jason Madden 6c081adb6a
Comments/changenote and simplify implementation of new_oid 2017-01-29 09:00:59 -06:00
Jason Madden 885f793bef
Monkey-patch for pre- zopefoundation/ZODB#139 versions. 2017-01-28 09:14:30 -06:00
Jason Madden d85c754025
Use decorators to replace a few more manual checks of self.keep_history. 2017-01-27 10:11:33 -06:00
Jason Madden b4e68abefe Merge pull request #158 from zodb/mysql-connector
Support for MySQL Connector/Python
2017-01-27 08:35:27 -06:00
Jason Madden cb7c1efa2a Merge pull request #157 from zodb/prep-statements
Performance work, especially on PostgreSQL
2017-01-26 12:26:16 -06:00
Jason Madden 8e7b49d2a6
Clean up mysqlconnector driver name. Clean up installation docs and driver statement docs. 2017-01-26 11:58:05 -06:00
Jason Madden 41b9670498
Cleanups
Comments about unicode for mysql connector should match reality, I hope.

Remove mysql_connection() and just pass the connection object to the one
place that needs it.
2017-01-26 10:21:04 -06:00
Jason Madden c79518e868
pylint 2017-01-25 18:04:08 -06:00
Jason Madden a2c398e1c2
Simplify lastrowid. Update comments. Simplify build matrix. 2017-01-25 17:57:20 -06:00
Jason Madden c5200e8138
Better DBAPI compliance: don't depend on cursor.rowcount and full resultset buffering
This is a good thing in general.

In MySQL Connectors case, it means we can get away from using the
`buffered=True` parameter when we get a cursor, which is a necessary
step to being able to use prepared cursors (because the two types can't
be combined).

It also *massively* improves performance. Using a buffered cursor,
running the testmysql tests took 173s with the python driver; using the
default unbuffered cursor they go to ~129s, which is comprable to
PyMySQL's ~125s. The C implemenattion goes to 115s (I didn't get a
before number for it) which is comprable to mysqlclient's 111s.

It makes me wonder what using unbuffered queries in those two
implementations might look like. mysqlclient appears to use one API call
to buffer the entire result set (mysql_store_result). PyMySQL seems to
iterate "packet" by packet, while connector/python iterates "row" by
row, which appear to be the same. This requires further testing.
2017-01-25 17:28:27 -06:00
Jason Madden 2787eebf08
Make sure that UndoableRecoveryStorage tests don't leak connections. See https://github.com/newtdb/db/pull/2 2017-01-25 13:24:07 -06:00
Jason Madden 45bf891321
Fix tests with python connector. Try to run both on travis. 2017-01-25 09:55:05 -06:00
Jason Madden 28f9b1ac56
Initial support for connector/python 2017-01-24 17:18:29 -06:00
Jason Madden 0184147633
umysqldb: translate 'cursor closed' into an exception RelStorage can deal with
Instead of silently reconnecting. That now causes issues with the
prepared statements.
2017-01-24 14:37:33 -06:00
Jason Madden df7e2b8147
pylint 2017-01-24 13:57:34 -06:00
Jason Madden 8648763019
Standardize the way get_latest_tid is prepared. 2017-01-24 12:39:21 -06:00
Jason Madden 1f131041b5
postgres 9.5+ use ON CONFLICT UPDATE for store_temp
This cuts out a DELETE statement for every object stored. On benchmarks
this is a 15-20% win compared to the last commit:

BEFORE

"Transaction",                postgresql
"Add 1000 Objects",                18042
"Update 1000 Objects",             19380

AFTER

"Transaction",                postgresql
"Add 1000 Objects",                20705
"Update 1000 Objects",             23568
2017-01-24 11:13:33 -06:00
Jason Madden 82dc954578
postgres 9.5+: use ON CONFLICT UPDATE to make temp permanent
Instead of a combination DELETE/INSERT statement. This gives us a 5-10%
performance increase.

BEFORE

"Transaction",                postgresql
"Add 1000 Objects",                17167
"Update 1000 Objects",             17314
"Read 1000 Warm Objects",          12575
"Read 1000 Cold Objects",          16714
"Read 1000 Hot Objects",           58357
"Read 1000 Steamin' Objects",    2124724

AFTER

"Transaction",                postgresql
"Add 1000 Objects",                18042
"Update 1000 Objects",             19380
"Read 1000 Warm Objects",          13611
"Read 1000 Cold Objects",          17970
"Read 1000 Hot Objects",           62971
"Read 1000 Steamin' Objects",    2069391
2017-01-24 10:40:25 -06:00
Jason Madden 12b46e13c4
disable paremeterized prepared statement for pg8000
I'm having trouble getting it to accept them right now
(https://github.com/mfenniak/pg8000/issues/132)
2017-01-24 07:51:21 -06:00
Jason Madden f6bab0a74b
Small but measurable write performance improvements
MySQL and PostgreSQL use a prepared statement to detect conflicts. This
is only noticeable when few objects are written.

Modernize the RowBatcher class by using defaultdict instead of manual
checks. Avoid doing some unnecessary sorting and defer string conversion
of deletes.
2017-01-23 18:30:52 -06:00
Jason Madden 1a0d92b6ca
Make load_current use a prepared statement in postgres
This shows gains up up to 40% for reading cold objects in zodbshooutout
0.6 tests with a fast local database.

BEFORE ANY (pg)

** concurrency=2 **
"Transaction",                postgresql
"Add 1000 Objects",                17202
"Update 1000 Objects",             14951
"Read 1000 Warm Objects",          11596
"Read 1000 Cold Objects",          12022
"Read 1000 Hot Objects",           60890
"Read 1000 Steamin' Objects",    2080069

WITH LOAD CURRENT

** concurrency=2 **
"Transaction",                postgresql
"Add 1000 Objects",                17896
"Update 1000 Objects",             17858
"Read 1000 Warm Objects",          14854
"Read 1000 Cold Objects",          16874
"Read 1000 Hot Objects",           62372
"Read 1000 Steamin' Objects",    2101126
2017-01-23 14:17:53 -06:00
Jason Madden 9513feeb97
Use a prepared statement for the mysql poll query. 2017-01-23 13:50:59 -06:00
Jason Madden b61274678a
Generalize the connmanager's hooks and start using them in PostgreSQL to prepare the get_latest_tid statement.
- Let there be multiple callables.
- Add a hook for load connections.
- Make subclassing easier. Removes a lot of duplicate code, especially
  from the oracle adapter.
- Use the hooks in postgresql to prepare get_latest_tid. This moves the
  query back into the place where the call to it is defined.
2017-01-23 13:27:56 -06:00
Jason Madden faa7861d23
Expose the HP/HF statement selection method that the mover uses and use it to clean up the poller. 2017-01-23 11:39:24 -06:00
Jason Madden 330d4b229a MySQL: Drop the commit lock after fill_object_refs (#150)
* format tweaks [skip ci]

* MySQL: Drop the commit lock after fill_object_refs

In pre-pack gc in a history-free storage.

Oracle and PostgreSQL were already doing this, so this should be a safe
change to make.

Fixes #9.

* Tweak error message.
2016-12-22 10:13:35 -06:00
Jason Madden 43336fa2ab
Optimize poller
Move almost all if keep_history: checks and subsequenty string
formatting and interning into __init__.
2016-12-21 18:07:33 -06:00
Jason Madden 8b264983ed
Update the OracleTransactionControl to use the GenericTransactionControl. Tested locally. 2016-12-21 09:17:56 -06:00
Jason Madden e3b21ffc67
Use optimized queries for getting the TID at commit time.
For MySQL and PostgreSQL only. MySQL uses the MAX query, and PostgreSQL
uses its prepared statement.

Also avoid checking self.keep_history at runtime, overriding the correct
methods dynamically.

cf #89
2016-12-21 08:58:03 -06:00
Jason Madden a1730bbdf8
Installation docs [skip ci] 2016-12-20 11:14:54 -06:00
Jason Madden 402c965b9f Test on Appveyor (#145)
* First basic version of appveyor.yml for testing. Still need to configure databases. Lets just see if we build.

* stdint.h is not available on MSVC before 2010, but we're not using it anyway. myssqlclient won't compile on windows

* Try a define for broken c99 support in MSVC.

* Broader macro.

* Use old form of 0 initializing struct.

* More fixes for broken c99 support of MSVC.

* Attempt to setup the database.

* need /c

* give up on running the DB tests.

* produce wheels

* produce wheels

* one more try for mysql tests.

* Run the db script as part of the test, it seems services aren't started during install phase.

* MySQL tests are running, try adding postgres.

* badges

* right bin directory for postgres

* Skip one blob test on windows/py3
2016-12-11 11:06:27 -06:00