This issue has been split from the original parent/meta issue #2001350: [meta] Drupal cannot be installed on PostgreSQL, but is now a follow-up issue and under #2157455: [Meta] Make Drupal 8 work with PostgreSQL or remove support from core before release.
Updated: Comment #7
Problem/Motivation
In transaction context, the first failure makes the transaction abort, and subsequent operations, even if they would normally succeed, also fail with the error "current transaction is aborted, commands ignored until end of transaction block". This differs from the behavior of MySQL. The workaround is to wrap all queries that occur inside a transaction with SAVEPOINT.
This issue is the root cause of many test failures on the PostgreSQL test bot, which is probably covering up general Drupal bugs that could be discovered through environment/platform test bots.
Other related issues that can be closed/retested when this is fixed:
- #2325421: Installer broken on PostgreSQL (again)
- #2303881: Config entity static cache doesn't get reset and isn't override aware
Proposed resolution
Damien Tournoud outlines the issue in Comment #12, which suggests the following resolutions:
- Add a save point and release after each query in the driver to mimic MySQL Innodb.
- Or mimic postgresql behavior in mysql and sqlite drivers by rolling back the entire transaction, which would also help exposed "hidden bugs" in Drupal that mysql is masking for us.
#1 was implemented using regular expression matching, but this did not pass code review by Crell in comment #117 . He offers some suggestions, but nothing to go on.
This issue is blocking several of the other PostgreSQL issues from being fully testable on PostgreSQL itself, but may not necessarily be a blocker to getting those issues fixed.
Patch Contributors
- fvideon, Damien Tournoud: initial issue patches and ideas
- mradcliffe: patch in this issue, new approach based on Crell's review.
- lokapujya: re-rolling patch to keep up with HEAD.
- bzrudi71, steinmb, grom358: manual testing & patch review
- ricardoamaro, jaredsmith: automated test bot & patch review
Remaining tasks
- Review & Commit
API changes
Yes, most likely. Needs to be documented here.
Comment | File | Size | Author |
---|---|---|---|
#38 | testbot-with-patch-33.txt | 179.99 KB | mradcliffe |
#33 | 2181291-32.patch | 8.78 KB | lokapujya |
#31 | drupal-2181291-pgsql-aborted-transaction-15_withDrush.txt | 207.4 KB | ricardoamaro |
#27 | drupal-2181291-pgsql-aborted-transaction-15.txt | 183.62 KB | ricardoamaro |
#15 | drupal-2181291-pgsql-aborted-transaction-15.patch | 9.06 KB | mradcliffe |
Comments
Comment #1
mradcliffeComment #2
mradcliffeHere's my progress in attempting to do something similar to the patch in the parent issue, but in the query classes.
There are two problems with this approach:
1. It's really repetitive code and would need to be done in each of the Query classes and any driver class that does a query.
2. The install proceeds swimmingly until a menu rebuild is called from menu.inc, which starts a brand new transaction via db_transaction(). The only code that uses db_transaction() is menu.inc and some test classes. I'm not sure if using pushTransaction or popTransaction is appropriate given db_transaction() exists.
My development process has been, in case any one is going to work on this, the following:
Comment #3
mradcliffePatch provides the following changes:
Is this the correct approach?
Edit: with this patch and the other patches, Drupal 8 installs on PostgreSQL 9.2.4.
Comment #4
mradcliffeAdded clarification to documentation to methods.
Removed inTransaction condition as that is done within pushTransaction and popTransaction respectively. Well popTransaction uses supportsTransaction, which is better. I attempted to just do away with those new methods and use push/pop, but I ran into some issues. I'll try that again later because I think I made a typo or something.
Comment #5
mradcliffeI probably should set this to needs work because of my last comment.
Comment #6
mradcliffeAdjusted parent issue.
Comment #7
mradcliffeComment #8
bzrudi71 CreditAttribution: bzrudi71 commentedSeems this effects currently broken HEAD, so adding as related:
#2254903: PostgreSQL install broken again in HEAD by toolbar module
Comment #9
mradcliffeStill needs work or run through tests to see what else is broken. The previous patches really screwed up transaction support. This patch should fix that and pass transaction tests.
Also this current patch means the band-aid fix is no longer necessary in #2325421: Installer broken on PostgreSQL (again) so think about removing that code in a patch if that gets in first.
Setting to NR first and then NW later.
Comment #10
ricardoamaro CreditAttribution: ricardoamaro commentedTesting this patch locally now...
Preparing a local environment:
Comment #11
mradcliffeComment #12
ricardoamaro CreditAttribution: ricardoamaro commentedRunning tests with patch:
~/drupalci_testbot# sudo DCI_PATCH="https://www.drupal.org/files/issues/drupal-2181291-pgsql-aborted-transaction-3.patch,." DCI_DBTYPE='pgsql' DCI_DBVER='9.1' DCI_TESTGROUPS='--all' DCI_DRUPALBRANCH='8.0.x' DCI_VERBOSE="true" DCI_CONCURRENCY="8" ./containers/web/run.sh
Comment #13
ricardoamaro CreditAttribution: ricardoamaro commentedWill paste the results in the end
Comment #14
ricardoamaro CreditAttribution: ricardoamaro commentedAttaching results
They seem to fail on:
Test run duration: 14 min 26 sec
Comment #15
mradcliffeOh, I forgot one little fix that I was trying out in another issue that helps. Finally making the change that other drivers made and not throwing PDOException because the application side no longer catches it.
Comment #16
hinfox CreditAttribution: hinfox commentedFor me it installs with the last patch applied (on PostgreSQL 9.3.5 Ubuntu 14.04.1 LTS 64 bit).
Comment #17
bzrudi71 CreditAttribution: bzrudi71 commentedJust startet run on PG testbot with latest patch applied (like in #12). Test is still running, but it seems we are back on track as most/all errors are gone and just leaving the ones we already know about. Big thanks @mradcliffe! Let's get this in after line by line review...
@ricardoamaro can you please crosscheck with my results? Thanks :-)
Comment #18
steinmb CreditAttribution: steinmb commentedPostgreSQL 9.3.4
Patch #15
Tested #15 and it came back green and it fixes the broken installer. Some warnings though, not sure if they are related to this or some of the other issues related to PostgreSQL problem.
Comment #19
mradcliffeThose are normal for Drupal 8. Drupal 8 installer WILL send garbage queries because of cache clears and it's up to the driver to handle not aborting everything because of it.
Comment #20
steinmb CreditAttribution: steinmb commentedThen I'm RTBC
Comment #21
ricardoamaro CreditAttribution: ricardoamaro commentedPer request i'm running:
Comment #22
ricardoamaro CreditAttribution: ricardoamaro commentedHere is the test stdout:
https://www.drupal.org/files/issues/results_drupal-2181291-pgsql-aborted...
Comment #23
mradcliffeI'm not sure if that's the right file you uploaded. The file tried to apply
Comment #25
ricardoamaro CreditAttribution: ricardoamaro commentedok, let me try and run this again.
Comment #26
mradcliffeI don't think this should be RTBC, which probably is confusing core committers.
Comment #27
ricardoamaro CreditAttribution: ricardoamaro commentedMy bad...
I did the tests again against patch 15 and here are the results:
https://www.drupal.org/files/issues/drupal-2181291-pgsql-aborted-transac...
Tell me if you need anything further ;)
Comment #28
mradcliffeI downgraded Postgresql to 9.1 (surprisingly painless with my puphpet config :-) and ran the following test that failed on the testbot. I did fetch and rebase to origin/8.0.x as 2014.09.06 23:50 UTC.
I'm not able to reproduce these test exceptions with the patch. I'll look more at the docs on your postgresql testbot to see what's different in config. Maybe the test bot is having trouble like in SQLite related to #2031261: Make SQLite faster by combining multiple inserts and updates in a single query, #2028713: Menu router does "too many SQL variables" on SQLite resulting in silent nondisplay of menu items, #1884182: Import of large number of translations fails on SQLite?
Comment #29
mradcliffeOh, hah. It is related. The new test bots store simpletest data in sqlite, which means #2031261: Make SQLite faster by combining multiple inserts and updates in a single query is related.
Comment #30
ricardoamaro CreditAttribution: ricardoamaro commented@mradcliffe would it help if i would tell the testbot to use drush installer?
Like this:
Let me start a test with these and post the results
Comment #31
ricardoamaro CreditAttribution: ricardoamaro commented@mradcliffe here are the results for a run using drush install:
https://www.drupal.org/files/issues/drupal-2181291-pgsql-aborted-transac...
Comment #32
lokapujyaRerolled. I'm able to run standard install with this patch.:
Mac OS X 10.9.4
PHP 5.5.17
Postgres 9.35
Comment #33
lokapujyaOops. patch is now attached.
Comment #34
jaredsmith CreditAttribution: jaredsmith commentedI've tested the patch and it works as advertised. I'm now able to go a clean installation on PostgreSQL from the 8.0.x branch. I've also read through the code of the patch, and agree that the code looks great.
My only concern, however, is that that we seem to be papering over a more fundamental problem in the installer code -- namely, that the installer tries to SELECT (and even worse, DELETE) from tables before they've been created. I don't know if this is really an expected thing (in which case, let's get this patch committed quickly), or unexpected (in which case, we should really fix the installation code).
Either way, I'd like to get this fixed sooner rather than later, and I'm willing to put some time into it here at DrupalCon Amsterdam.
Comment #35
mradcliffeMy only concern are the test results from @ricardoamaro's test bot from earlier and trying to reconcile those with not being able to reproduce no my vagrant environment.
Comment #36
mradcliffeOk, it looks like changes in the test bot since 3 weeks ago fixed some things, and with patching #32 we can get clean tests on Database group and various others that allow things to install.
Waiting on http://testbot.drupal-pt.org/node/381
Comment #37
grom358 CreditAttribution: grom358 commentedAlternative to doing savepoints in code is by using ON_ERROR_ROLLBACK.
I also have to agree with #34, the installer shouldn't do SELECT or DELETE on non-existent tables.
Performance wise, I found this old post saying average slowdown of 12%. I wasn't able to find benchmarks for version 9 of postgres.
Comment #38
mradcliffeLatest test bot results attached from ricardo's test bot. 206 exceptions should show pretty much all of the bugs in Drupal 8 wrt to PostgreSQL. I'd say the patch is successful given manual testing and test bot runs.
Setting to Needs review for the moment to look at performance if we care about that.
Comment #39
bzrudi71 CreditAttribution: bzrudi71 commentedJust did a quick grep and it doesn't seem that Drupal makes heavily use of transactions. There are some transactions in the Entity System and mostly in storage context. So I guess we are save here in regards of performance...
Comment #41
ricardoamaro CreditAttribution: ricardoamaro commentedComment #42
mradcliffeJust did a bit of reading to confirm that the uniqueness of the save point name. "If multiple savepoints have the same name, only the one that was most recently defined is released." This should not cause anything to leak out on Exceptions, which is @Damien Tournoud's concern.
We discussed this briefly this morning about being re-entrant, and if so, that may be an additional bug in some other part of Drupal core (or contrib).
I'd say I'm confident in this being RTBC.
Comment #43
mradcliffeAdded patch contributors to issue summary.
Comment #44
webchickUm. That's crazy that this wasn't implemented before?!
Anyway, this only touches the pgsql lib so looks safe to commit. GREAT work on this effort, folks! Onward to 100% passing tests!
Committed and pushed to 8.x. Thanks! I'm pretty sure I got everyone in the commit message. :)
Comment #47
bzrudi71 CreditAttribution: bzrudi71 commentedCommentTestBook test fails because of:
Drupal\Core\Entity\EntityStorageException: mimic_implicit_commit is already in use.
Please see #2356967: PostgreSQL: Fix tests in comment test group.
Follow-up?
Comment #48
grom358 CreditAttribution: grom358 commentedStill think it simpler to use ON_ERROR_ROLLBACK. Have that option turned on when establishing the connection. Bonus of being a lot less code, be one extra line of code when connection is established instead of all this code to wrap queries with creating explicit savepoints.
What pros of doing it with code? what are the cons with using ON_ERROR_ROLLBACK option?
Comment #49
bzrudi71 CreditAttribution: bzrudi71 commented@grom358 the ON_ERROR_ROLLBACK option is not a feature of the PostgreSQL server itself. It's a feature of the PostgreSQL client(s) and as far as I can see not supported by PDO. Anyway, it does exactly the same as this patch does (adding SAVEPOINTS), so there will be no profit in terms of performance ;-)
Comment #50
grom358 CreditAttribution: grom358 commented@bzrudi71 correct you are. I just assumed the driver would support it. I was not suggesting it for performance reasons but in reducing the code needed to be maintained.
Besides the installer (which I notice has been marked as fixed) where else in Drupal does it make use of implict savepoints?
This patch means have the same behaviour as MySQL. But wether that is a good thing here is the question. Personally I think can be problematic if we committing a transaction that happen to contain SQL statements that errored.