~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
27
27
 * Portions Copyright (c) 1994, Regents of the University of California
28
28
 *
29
 
 * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.52 2009/01/20 18:59:37 heikki Exp $
 
29
 * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.53 2009/06/11 14:48:54 momjian Exp $
30
30
 *
31
31
 *-------------------------------------------------------------------------
32
32
 */
81
81
static void WriteZeroPageXlogRec(int pageno);
82
82
static void WriteTruncateXlogRec(int pageno);
83
83
static void TransactionIdSetPageStatus(TransactionId xid, int nsubxids,
84
 
                                                   TransactionId *subxids, XidStatus status,
 
84
                                                   TransactionId *subxids, XidStatus status,
85
85
                                                   XLogRecPtr lsn, int pageno);
86
86
static void TransactionIdSetStatusBit(TransactionId xid, XidStatus status,
87
87
                                                  XLogRecPtr lsn, int slotno);
112
112
 * the same CLOG page as xid.  If they all are, then the lock will be grabbed
113
113
 * only once, and the status will be set to committed directly.  Otherwise
114
114
 * we must
115
 
 *   1. set sub-committed all subxids that are not on the same page as the
116
 
 *      main xid
117
 
 *   2. atomically set committed the main xid and the subxids on the same page
118
 
 *   3. go over the first bunch again and set them committed
 
115
 *       1. set sub-committed all subxids that are not on the same page as the
 
116
 *              main xid
 
117
 *       2. atomically set committed the main xid and the subxids on the same page
 
118
 *       3. go over the first bunch again and set them committed
119
119
 * Note that as far as concurrent checkers are concerned, main transaction
120
120
 * commit as a whole is still atomic.
121
121
 *
126
126
 *                                      page2: set t2,t3 as sub-committed
127
127
 *                                      page3: set t4 as sub-committed
128
128
 *              2. update page1:
129
 
 *                                      set t1 as sub-committed, 
 
129
 *                                      set t1 as sub-committed,
130
130
 *                                      then set t as committed,
131
131
                                        then set t1 as committed
132
132
 *              3. update pages2-3:
133
133
 *                                      page2: set t2,t3 as committed
134
134
 *                                      page3: set t4 as committed
135
 
 * 
 
135
 *
136
136
 * NB: this is a low-level routine and is NOT the preferred entry point
137
137
 * for most uses; functions in transam.c are the intended callers.
138
138
 *
142
142
 */
143
143
void
144
144
TransactionIdSetTreeStatus(TransactionId xid, int nsubxids,
145
 
                                TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
 
145
                                        TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
146
146
{
147
 
        int             pageno = TransactionIdToPage(xid); /* get page of parent */
148
 
        int     i;
 
147
        int                     pageno = TransactionIdToPage(xid);              /* get page of parent */
 
148
        int                     i;
149
149
 
150
150
        Assert(status == TRANSACTION_STATUS_COMMITTED ||
151
151
                   status == TRANSACTION_STATUS_ABORTED);
152
152
 
153
153
        /*
154
 
         * See how many subxids, if any, are on the same page as the parent, if any.
 
154
         * See how many subxids, if any, are on the same page as the parent, if
 
155
         * any.
155
156
         */
156
157
        for (i = 0; i < nsubxids; i++)
157
158
        {
172
173
        }
173
174
        else
174
175
        {
175
 
                int             nsubxids_on_first_page = i;
 
176
                int                     nsubxids_on_first_page = i;
176
177
 
177
178
                /*
178
179
                 * If this is a commit then we care about doing this correctly (i.e.
179
 
                 * using the subcommitted intermediate status).  By here, we know we're
180
 
                 * updating more than one page of clog, so we must mark entries that
181
 
                 * are *not* on the first page so that they show as subcommitted before
182
 
                 * we then return to update the status to fully committed.
 
180
                 * using the subcommitted intermediate status).  By here, we know
 
181
                 * we're updating more than one page of clog, so we must mark entries
 
182
                 * that are *not* on the first page so that they show as subcommitted
 
183
                 * before we then return to update the status to fully committed.
183
184
                 *
184
185
                 * To avoid touching the first page twice, skip marking subcommitted
185
186
                 * for the subxids on that first page.
217
218
set_status_by_pages(int nsubxids, TransactionId *subxids,
218
219
                                        XidStatus status, XLogRecPtr lsn)
219
220
{
220
 
        int             pageno = TransactionIdToPage(subxids[0]);
221
 
        int             offset = 0;
222
 
        int             i = 0;
 
221
        int                     pageno = TransactionIdToPage(subxids[0]);
 
222
        int                     offset = 0;
 
223
        int                     i = 0;
223
224
 
224
225
        while (i < nsubxids)
225
226
        {
226
 
                int             num_on_page = 0;
 
227
                int                     num_on_page = 0;
227
228
 
228
229
                while (TransactionIdToPage(subxids[i]) == pageno && i < nsubxids)
229
230
                {
251
252
                                                   XLogRecPtr lsn, int pageno)
252
253
{
253
254
        int                     slotno;
254
 
        int             i;
 
255
        int                     i;
255
256
 
256
257
        Assert(status == TRANSACTION_STATUS_COMMITTED ||
257
258
                   status == TRANSACTION_STATUS_ABORTED ||
275
276
         *
276
277
         * If we update more than one xid on this page while it is being written
277
278
         * out, we might find that some of the bits go to disk and others don't.
278
 
         * If we are updating commits on the page with the top-level xid that could
279
 
         * break atomicity, so we subcommit the subxids first before we mark the
280
 
         * top-level commit.
 
279
         * If we are updating commits on the page with the top-level xid that
 
280
         * could break atomicity, so we subcommit the subxids first before we mark
 
281
         * the top-level commit.
281
282
         */
282
283
        if (TransactionIdIsValid(xid))
283
284
        {
336
337
                curval == TRANSACTION_STATUS_COMMITTED)
337
338
                return;
338
339
 
339
 
        /* 
 
340
        /*
340
341
         * Current state change should be from 0 or subcommitted to target state
341
342
         * or we should already be there when replaying changes during recovery.
342
343
         */