~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/backend/access/transam/multixact.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Peter Eisentraut, Martin Pitt
  • Date: 2009-12-14 19:02:38 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20091214190238-ubwqbnzwbhbc9b9f
Tags: 8.4.2-1
Medium urgency due to security fixes.

[ Peter Eisentraut ]
* debian/control: Added Homepage
* debian/control: Added ${misc:Depends} on all packages, per lintian
* debian/control: Added versioned dependencies on the shared libraries used 
  by the libecpg-dev package
* debian/control: Removed obsolete build dependency bzip2
* debian/control: Added Vcs fields

[ Martin Pitt ]
* New upstream security/bug fix release:
  - Protect against indirect security threats caused by index functions
    changing session-local state. This change prevents allegedly-immutable
    index functions from possibly subverting a superuser's session
    (CVE-2009-4136).
  - Reject SSL certificates containing an embedded null byte in the
    common name (CN) field. This prevents unintended matching of a
    certificate to a server or client name during SSL validation
    (CVE-2009-4034).
  - Fix hash index corruption. The 8.4 change that made hash indexes keep
    entries sorted by hash value failed to update the bucket splitting and
    compaction routines to preserve the ordering. So application of either
    of those operations could lead to permanent corruption of an index, in
    the sense that searches might fail to find entries that are present. To
    deal with this, it is recommended to REINDEX any hash indexes you may
    have after installing this update.
  - Fix possible crash during backend-startup-time cache initialization.
  - Avoid crash on empty thesaurus dictionary.
  - Prevent signals from interrupting VACUUM at unsafe times.
  - Fix possible crash due to integer overflow in hash table size
    calculation.
  - Fix crash if a DROP is attempted on an internally-dependent object.
  - Fix very rare crash in inet/cidr comparisons.
  - Ensure that shared tuple-level locks held by prepared transactions
    are not ignored.
  - Fix premature drop of temporary files used for a cursor that is
    accessed within a subtransaction.
  - Fix memory leak in syslogger process when rotating to a new CSV
    logfile.
  - Fix memory leak in postmaster when re-parsing "pg_hba.conf".
  - Make FOR UPDATE/SHARE in the primary query not propagate into WITH
    queries.
  - Fix bug with a WITH RECURSIVE query immediately inside another one.
  - Fix concurrency bug in hash indexes.
  - Fix incorrect logic for GiST index page splits, when the split
    depends on a non-first column of the index.
  - Fix wrong search results for a multi-column GIN index with
    fastupdate enabled.
  - Fix bugs in WAL entry creation for GIN indexes.
  - Don't error out if recycling or removing an old WAL file fails at
    the end of checkpoint.
  - Fix PAM password processing to be more robust.
    The previous code is known to fail with the combination of the
    Linux pam_krb5 PAM module with Microsoft Active Directory as the
    domain controller. It might have problems elsewhere too, since it
    was making unjustified assumptions about what arguments the PAM
    stack would pass to it.
  - Raise the maximum authentication token (Kerberos ticket) size in
    GSSAPI and SSPI authentication methods. While the old 2000-byte limit
    was more than enough for Unix Kerberos implementations, tickets issued
    by Windows Domain Controllers can be much larger.
  - Ensure that domain constraints are enforced in constructs like
    ARRAY[...]::domain, where the domain is over an array type.
  - Fix foreign-key logic for some cases involving composite-type
    columns as foreign keys.
  - Ensure that a cursor's snapshot is not modified after it is created.
  - Fix CREATE TABLE to properly merge default expressions coming from
    different inheritance parent tables. This used to work but was broken in
    8.4.
  - Re-enable collection of access statistics for sequences. This used to
    work but was broken in 8.3.
  - Fix processing of ownership dependencies during CREATE OR REPLACE
    FUNCTION.
  - Fix incorrect handling of WHERE "x"="x" conditions.
    In some cases these could get ignored as redundant, but they aren't
    -- they're equivalent to "x" IS NOT NULL.
  - Fix incorrect plan construction when using hash aggregation to
    implement DISTINCT for textually identical volatile expressions
  - Fix Assert failure for a volatile SELECT DISTINCT ON expression
  - Fix ts_stat() to not fail on an empty tsvector value
  - Make text search parser accept underscores in XML attributes
  - Fix encoding handling in xml binary input.
    If the XML header doesn't specify an encoding, we now assume UTF-8
    by default; the previous handling was inconsistent.
  - Fix bug with calling plperl from plperlu or vice versa.
  - Fix session-lifespan memory leak when a PL/Perl function is
    redefined.
  - Ensure that Perl arrays are properly converted to PostgreSQL arrays
    when returned by a set-returning PL/Perl function.
  - Fix rare crash in exception processing in PL/Python.
  - Fix ecpg problem with comments in DECLARE CURSOR statements
  - Fix ecpg to not treat recently-added keywords as reserved words
    This affected the keywords CALLED, CATALOG, DEFINER, ENUM,
    FOLLOWING, INVOKER, OPTIONS, PARTITION, PRECEDING, RANGE, SECURITY,
    SERVER, UNBOUNDED, and WRAPPER.
  - Re-allow regular expression special characters in psql's \df
    function name parameter.
  - Put FREEZE and VERBOSE options in the right order in the VACUUM
    command that "contrib/vacuumdb" produces.
  - Fix possible leak of connections when "contrib/dblink" encounters
    an error
  - Make the postmaster ignore any application_name parameter in
    connection request packets, to improve compatibility with future
    libpq versions.
* debian/control: libreadline5-dev → libreadline-dev. (Closes: #553831)
* Add 03-sh-architecture.patch: Support Renesas' SuperH architecture, thanks
  Nobuhiro Iwamatsu! (Closes: #548847)

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
43
43
 * Portions Copyright (c) 1994, Regents of the University of California
44
44
 *
45
 
 * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.31 2009/06/26 20:29:04 tgl Exp $
 
45
 * $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.31.2.1 2009/11/23 09:58:51 heikki Exp $
46
46
 *
47
47
 *-------------------------------------------------------------------------
48
48
 */
51
51
#include "access/multixact.h"
52
52
#include "access/slru.h"
53
53
#include "access/transam.h"
 
54
#include "access/twophase.h"
 
55
#include "access/twophase_rmgr.h"
54
56
#include "access/xact.h"
55
57
#include "miscadmin.h"
56
58
#include "pg_trace.h"
118
120
        /*
119
121
         * Per-backend data starts here.  We have two arrays stored in the area
120
122
         * immediately following the MultiXactStateData struct. Each is indexed by
121
 
         * BackendId.  (Note: valid BackendIds run from 1 to MaxBackends; element
122
 
         * zero of each array is never used.)
 
123
         * BackendId.
 
124
         *
 
125
         * In both arrays, there's a slot for all normal backends (1..MaxBackends)
 
126
         * followed by a slot for max_prepared_xacts prepared transactions. Valid
 
127
         * BackendIds start from 1; element zero of each array is never used.
123
128
         *
124
129
         * OldestMemberMXactId[k] is the oldest MultiXactId each backend's current
125
130
         * transaction(s) could possibly be a member of, or InvalidMultiXactId
152
157
        MultiXactId perBackendXactIds[1];       /* VARIABLE LENGTH ARRAY */
153
158
} MultiXactStateData;
154
159
 
 
160
/*
 
161
 * Last element of OldestMemberMXactID and OldestVisibleMXactId arrays.
 
162
 * Valid elements are (1..MaxOldestSlot); element 0 is never used.
 
163
 */
 
164
#define MaxOldestSlot   (MaxBackends + max_prepared_xacts)
 
165
 
155
166
/* Pointers to the state data in shared memory */
156
167
static MultiXactStateData *MultiXactState;
157
168
static MultiXactId *OldestMemberMXactId;
539
550
                if (oldestMXact < FirstMultiXactId)
540
551
                        oldestMXact = FirstMultiXactId;
541
552
 
542
 
                for (i = 1; i <= MaxBackends; i++)
 
553
                for (i = 1; i <= MaxOldestSlot; i++)
543
554
                {
544
555
                        MultiXactId thisoldest = OldestMemberMXactId[i];
545
556
 
1276
1287
}
1277
1288
 
1278
1289
/*
 
1290
 * AtPrepare_MultiXact
 
1291
 *              Save multixact state at 2PC tranasction prepare
 
1292
 *
 
1293
 * In this phase, we only store our OldestMemberMXactId value in the two-phase
 
1294
 * state file.
 
1295
 */
 
1296
void
 
1297
AtPrepare_MultiXact(void)
 
1298
{
 
1299
        MultiXactId myOldestMember = OldestMemberMXactId[MyBackendId];
 
1300
 
 
1301
        if (MultiXactIdIsValid(myOldestMember))
 
1302
                RegisterTwoPhaseRecord(TWOPHASE_RM_MULTIXACT_ID, 0,
 
1303
                                                           &myOldestMember, sizeof(MultiXactId));
 
1304
}
 
1305
 
 
1306
/*
 
1307
 * PostPrepare_MultiXact
 
1308
 *              Clean up after successful PREPARE TRANSACTION
 
1309
 */
 
1310
void
 
1311
PostPrepare_MultiXact(TransactionId xid)
 
1312
{
 
1313
        MultiXactId myOldestMember;
 
1314
 
 
1315
        /*
 
1316
         * Transfer our OldestMemberMXactId value to the slot reserved for the
 
1317
         * prepared transaction.
 
1318
         */
 
1319
        myOldestMember = OldestMemberMXactId[MyBackendId];
 
1320
        if (MultiXactIdIsValid(myOldestMember))
 
1321
        {
 
1322
                BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid);
 
1323
 
 
1324
                /*
 
1325
                 * Even though storing MultiXactId is atomic, acquire lock to make sure
 
1326
                 * others see both changes, not just the reset of the slot of the
 
1327
                 * current backend. Using a volatile pointer might suffice, but this
 
1328
                 * isn't a hot spot.
 
1329
                 */
 
1330
                LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
 
1331
 
 
1332
                OldestMemberMXactId[dummyBackendId] = myOldestMember;
 
1333
                OldestMemberMXactId[MyBackendId] = InvalidMultiXactId;
 
1334
 
 
1335
                LWLockRelease(MultiXactGenLock);
 
1336
        }
 
1337
 
 
1338
        /*
 
1339
         * We don't need to transfer OldestVisibleMXactId value, because the
 
1340
         * transaction is not going to be looking at any more multixacts once
 
1341
         * it's prepared.
 
1342
         *
 
1343
         * We assume that storing a MultiXactId is atomic and so we need not take
 
1344
         * MultiXactGenLock to do this.
 
1345
         */
 
1346
        OldestVisibleMXactId[MyBackendId] = InvalidMultiXactId;
 
1347
 
 
1348
        /*
 
1349
         * Discard the local MultiXactId cache like in AtEOX_MultiXact
 
1350
         */
 
1351
        MXactContext = NULL;
 
1352
        MXactCache = NULL;
 
1353
}
 
1354
 
 
1355
/*
 
1356
 * multixact_twophase_recover
 
1357
 *              Recover the state of a prepared transaction at startup
 
1358
 */
 
1359
void
 
1360
multixact_twophase_recover(TransactionId xid, uint16 info,
 
1361
                                                   void *recdata, uint32 len)
 
1362
{
 
1363
        BackendId       dummyBackendId = TwoPhaseGetDummyBackendId(xid);
 
1364
        MultiXactId     oldestMember;
 
1365
 
 
1366
        /*
 
1367
         * Get the oldest member XID from the state file record, and set it in
 
1368
         * the OldestMemberMXactId slot reserved for this prepared transaction.
 
1369
         */
 
1370
        Assert(len == sizeof(MultiXactId));
 
1371
        oldestMember = *((MultiXactId *)recdata);
 
1372
 
 
1373
        OldestMemberMXactId[dummyBackendId] = oldestMember;
 
1374
}
 
1375
 
 
1376
/*
 
1377
 * multixact_twophase_postcommit
 
1378
 *              Similar to AtEOX_MultiXact but for COMMIT PREPARED
 
1379
 */
 
1380
void
 
1381
multixact_twophase_postcommit(TransactionId xid, uint16 info,
 
1382
                                                          void *recdata, uint32 len)
 
1383
{
 
1384
        BackendId       dummyBackendId = TwoPhaseGetDummyBackendId(xid);
 
1385
 
 
1386
        Assert(len == sizeof(MultiXactId));
 
1387
 
 
1388
        OldestMemberMXactId[dummyBackendId] = InvalidMultiXactId;
 
1389
}
 
1390
 
 
1391
/*
 
1392
 * multixact_twophase_postabort
 
1393
 *              This is actually just the same as the COMMIT case.
 
1394
 */
 
1395
void
 
1396
multixact_twophase_postabort(TransactionId xid, uint16 info,
 
1397
                                                void *recdata, uint32 len)
 
1398
{
 
1399
        multixact_twophase_postcommit(xid, info, recdata, len);
 
1400
}
 
1401
 
 
1402
/*
1279
1403
 * Initialization of shared memory for MultiXact.  We use two SLRU areas,
1280
1404
 * thus double memory.  Also, reserve space for the shared MultiXactState
1281
1405
 * struct and the per-backend MultiXactId arrays (two of those, too).
1287
1411
 
1288
1412
#define SHARED_MULTIXACT_STATE_SIZE \
1289
1413
        add_size(sizeof(MultiXactStateData), \
1290
 
                         mul_size(sizeof(MultiXactId) * 2, MaxBackends))
 
1414
                         mul_size(sizeof(MultiXactId) * 2, MaxOldestSlot))
1291
1415
 
1292
1416
        size = SHARED_MULTIXACT_STATE_SIZE;
1293
1417
        size = add_size(size, SimpleLruShmemSize(NUM_MXACTOFFSET_BUFFERS, 0));
1329
1453
 
1330
1454
        /*
1331
1455
         * Set up array pointers.  Note that perBackendXactIds[0] is wasted space
1332
 
         * since we only use indexes 1..MaxBackends in each array.
 
1456
         * since we only use indexes 1..MaxOldestSlot in each array.
1333
1457
         */
1334
1458
        OldestMemberMXactId = MultiXactState->perBackendXactIds;
1335
 
        OldestVisibleMXactId = OldestMemberMXactId + MaxBackends;
 
1459
        OldestVisibleMXactId = OldestMemberMXactId + MaxOldestSlot;
1336
1460
}
1337
1461
 
1338
1462
/*
1702
1826
                nextMXact = FirstMultiXactId;
1703
1827
 
1704
1828
        oldestMXact = nextMXact;
1705
 
        for (i = 1; i <= MaxBackends; i++)
 
1829
        for (i = 1; i <= MaxOldestSlot; i++)
1706
1830
        {
1707
1831
                MultiXactId thisoldest;
1708
1832