On Tue, 2007-02-20 at 14:38 -0300, Alvaro Herrera wrote: > Cool. I noticed that the SGML seems broken here:
Corrected. > You need to close the <listitem> and <para> opened in the COPY mention. > > > + > > + static void > > + heap_sync_relation(Relation rel) > > + { > > + if (!rel->rd_istemp) > > No comment in this function? I've added more comments as you suggest. Thanks for the review. -- Simon Riggs EnterpriseDB http://www.enterprisedb.com
Index: doc/src/sgml/perform.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/perform.sgml,v retrieving revision 1.63 diff -c -r1.63 perform.sgml *** doc/src/sgml/perform.sgml 1 Feb 2007 19:10:24 -0000 1.63 --- doc/src/sgml/perform.sgml 22 Feb 2007 11:50:58 -0000 *************** *** 908,919 **** will perform more slowly when <varname>archive_command</varname> is set, as a result of their needing to write large amounts of WAL. This applies to the following commands: ! <command>CREATE TABLE AS SELECT</command>, ! <command>CREATE INDEX</command> and also <command>COPY</command>, when ! it is executed in the same transaction as a prior ! <command>CREATE TABLE</command> or <command>TRUNCATE</command> command. ! </para> ! </sect2> <sect2 id="populate-analyze"> --- 908,928 ---- will perform more slowly when <varname>archive_command</varname> is set, as a result of their needing to write large amounts of WAL. This applies to the following commands: ! <itemizedlist> ! <listitem><para><command>CREATE TABLE AS SELECT</command></para></listitem> ! <listitem><para><command>CREATE INDEX</command></para></listitem> ! <listitem><para><command>ALTER TABLE SET TABLESPACE</command></para></listitem> ! <listitem><para><command>CLUSTER</command></para></listitem> ! <listitem> ! <para><command>COPY</command>, when it is executed after one of ! these commands, yet in the same transaction: ! <itemizedlist> ! <listitem><para><command>CREATE TABLE</command></para></listitem> ! <listitem><para><command>TRUNCATE</command></para></listitem> ! </itemizedlist> ! </para> ! </listitem> ! </itemizedlist> </sect2> <sect2 id="populate-analyze"> *************** *** 950,964 **** By default, <application>pg_dump</> uses <command>COPY</>, and when it is generating a complete schema-and-data dump, it is careful to load data before creating indexes and foreign keys. So in this case ! the first several guidelines are handled automatically. What is left ! for you to do is to set appropriate (i.e., larger than normal) values ! for <varname>maintenance_work_mem</varname> and ! <varname>checkpoint_segments</varname>, as well as unsetting ! <varname>archive_command</varname> before loading the dump script, ! and then to run <command>ANALYZE</> afterwards and resetting ! <varname>archive_command</varname> if required. All of the ! parameters can be reset once the load has completed without needing ! to restart the server, as described in <xref linkend="config-setting">. </para> <para> --- 959,992 ---- By default, <application>pg_dump</> uses <command>COPY</>, and when it is generating a complete schema-and-data dump, it is careful to load data before creating indexes and foreign keys. So in this case ! several guidelines are handled automatically. What is left ! for you to do is to: ! <itemizedlist> ! <listitem><para>Set appropriate (i.e., larger than normal) values ! for <varname>maintenance_work_mem</varname> and ! <varname>checkpoint_segments</varname>.</para></listitem> ! <listitem><para>Unset <varname>archive_command</varname> before ! loading the dump script, and then reset ! <varname>archive_command</varname> afterwards, if required.</para> ! </listitem> ! <listitem> ! <para> ! Consider whether the whole dump can be restored as a single ! transaction, so that COPY commands can be optimized. Remember that ! this will mean that all restore commands will either fully completed ! or fully rolled back. This mode can be specified by passing the ! <option>-1</> or <option>--single-transaction</> command-line options ! to <application>psql</> or <application>pg_restore</>. When using this ! mode, be aware that even the smallest of errors can rollback a ! restore that has already run for many hours. However, that might ! still be preferable to manually cleaning up a complex database ! after a partially restored dump. ! </para> ! </listitem> ! <listitem><para>Run <command>ANALYZE</> afterwards.</para></listitem> ! All of the above mentioned parameters can be reset once the load has ! completed without needing to restart the server, as described in ! <xref linkend="config-setting">. </para> <para> Index: src/backend/access/heap/heapam.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/access/heap/heapam.c,v retrieving revision 1.228 diff -c -r1.228 heapam.c *** src/backend/access/heap/heapam.c 9 Feb 2007 03:35:33 -0000 1.228 --- src/backend/access/heap/heapam.c 22 Feb 2007 11:51:00 -0000 *************** *** 60,65 **** --- 60,66 ---- static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move); + static void heap_sync_relation(Relation rel); /* ---------------------------------------------------------------- *************** *** 3991,3996 **** --- 3992,4003 ---- /* ---------------- * heap_sync - sync a heap, for use when no WAL has been written * + * Will sync all relations associated with the main table, + * i.e. the main heap, indexes, the toast relation and its index + * If new relation types were added, this would need extension + * XXX Indexes are mentioned because its possible in the future that + * we may choose to avoid writing WAL for indexes as well, + * in certain cicrumstances. * ---------------- */ void *************** *** 3998,4003 **** --- 4005,4042 ---- { if (!rel->rd_istemp) { + /* main heap */ + heap_sync_relation(rel); + + /* main heap indexes, if any */ + /* we always use WAL for index inserts, so no need to sync */ + + /* toast heap, if any */ + if (OidIsValid(rel->rd_rel->reltoastrelid)) + { + Relation toastrel; + + toastrel = heap_open(rel->rd_rel->reltoastrelid, + AccessShareLock); + heap_sync_relation(toastrel); + heap_close(toastrel, AccessShareLock); + } + + /* toast index, if toast heap */ + /* we always use WAL for index inserts, so no need to sync */ + } + } + + /* + * heap_sync_relation + * + * Worker function for heap_sync(). Performs sync for an individual relation. + */ + static void + heap_sync_relation(Relation rel) + { + if (!rel->rd_istemp) + { /* * If we skipped using WAL, and it's not a temp relation, * we must force the relation down to disk before it's Index: src/backend/commands/cluster.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/cluster.c,v retrieving revision 1.156 diff -c -r1.156 cluster.c *** src/backend/commands/cluster.c 1 Feb 2007 19:10:25 -0000 1.156 --- src/backend/commands/cluster.c 22 Feb 2007 11:51:00 -0000 *************** *** 653,658 **** --- 653,659 ---- char *nulls; IndexScanDesc scan; HeapTuple tuple; + bool use_wal; /* * Open the relations we need. *************** *** 676,681 **** --- 677,688 ---- memset(nulls, 'n', natts * sizeof(char)); /* + * We need to log the copied data in WAL iff WAL archiving is enabled AND + * it's not a temp rel. + */ + use_wal = XLogArchivingActive() && !NewHeap->rd_istemp; + + /* * Scan through the OldHeap on the OldIndex and copy each tuple into the * NewHeap. */ *************** *** 722,728 **** if (NewHeap->rd_rel->relhasoids) HeapTupleSetOid(copiedTuple, HeapTupleGetOid(tuple)); ! simple_heap_insert(NewHeap, copiedTuple); heap_freetuple(copiedTuple); --- 729,735 ---- if (NewHeap->rd_rel->relhasoids) HeapTupleSetOid(copiedTuple, HeapTupleGetOid(tuple)); ! fast_heap_insert(NewHeap, copiedTuple, use_wal); heap_freetuple(copiedTuple); *************** *** 736,741 **** --- 743,752 ---- index_close(OldIndex, NoLock); heap_close(OldHeap, NoLock); + + if (!use_wal) + heap_sync(NewHeap); + heap_close(NewHeap, NoLock); } Index: src/backend/commands/copy.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/copy.c,v retrieving revision 1.276 diff -c -r1.276 copy.c *** src/backend/commands/copy.c 20 Feb 2007 17:32:13 -0000 1.276 --- src/backend/commands/copy.c 22 Feb 2007 11:51:01 -0000 *************** *** 1857,1863 **** * do not need to worry about inconsistent states. * As mentioned in comments in utils/rel.h, the in-same-transaction test is * not completely reliable, since rd_createSubId can be reset to zero in ! * certain cases before the end of the creating transaction. * We are doing this for performance only, so we only need to know: * if rd_createSubid != InvalidSubTransactionId then it is *always* just * created. If we have PITR enabled, then we *must* use_wal --- 1857,1865 ---- * do not need to worry about inconsistent states. * As mentioned in comments in utils/rel.h, the in-same-transaction test is * not completely reliable, since rd_createSubId can be reset to zero in ! * certain cases before the end of the creating transaction. ! * CLUSTER creates a new relfilenode but it removes the old one immediately ! * for other reasons, so we cannot optimise COPY following CLUSTER. * We are doing this for performance only, so we only need to know: * if rd_createSubid != InvalidSubTransactionId then it is *always* just * created. If we have PITR enabled, then we *must* use_wal *************** *** 2121,2148 **** * If we skipped writing WAL for heaps, then we need to sync */ if (!use_wal) - { - /* main heap */ heap_sync(cstate->rel); - /* main heap indexes, if any */ - /* we always use WAL for index inserts, so no need to sync */ - - /* toast heap, if any */ - if (OidIsValid(cstate->rel->rd_rel->reltoastrelid)) - { - Relation toastrel; - - toastrel = heap_open(cstate->rel->rd_rel->reltoastrelid, - AccessShareLock); - heap_sync(toastrel); - heap_close(toastrel, AccessShareLock); - } - - /* toast index, if toast heap */ - /* we always use WAL for index inserts, so no need to sync */ - } - /* Done, clean up */ error_context_stack = errcontext.previous; --- 2123,2130 ----
---------------------------(end of broadcast)--------------------------- TIP 5: don't forget to increase your free space map settings