Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit bbc6dda

Browse files
committed
Merge branch 'PGPRO10' into PGPROEE10
2 parents 5b7bdfb + 9f175cb commit bbc6dda

File tree

26 files changed

+419
-88
lines changed

26 files changed

+419
-88
lines changed

contrib/pageinspect/hashfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,10 @@ hash_page_items(PG_FUNCTION_ARGS)
313313

314314
fctx = SRF_FIRSTCALL_INIT();
315315

316-
page = verify_hash_page(raw_page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
317-
318316
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
319317

318+
page = verify_hash_page(raw_page, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
319+
320320
uargs = palloc(sizeof(struct user_args));
321321

322322
uargs->page = page;

doc/src/sgml/ddl.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,14 +3077,14 @@ CREATE TABLE measurement (
30773077

30783078
<programlisting>
30793079
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
3080-
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01')
3080+
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
30813081

30823082
CREATE TABLE measurement_y2006m03 PARTITION OF measurement
3083-
FOR VALUES FROM ('2006-03-01') TO ('2006-04-01')
3083+
FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
30843084

30853085
...
30863086
CREATE TABLE measurement_y2007m11 PARTITION OF measurement
3087-
FOR VALUES FROM ('2007-11-01') TO ('2007-12-01')
3087+
FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
30883088

30893089
CREATE TABLE measurement_y2007m12 PARTITION OF measurement
30903090
FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')

doc/src/sgml/libpq.sgml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7612,11 +7612,10 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
76127612
To allow the client to verify the identity of the server, place a root
76137613
certificate on the client and a leaf certificate signed by the root
76147614
certificate on the server. To allow the server to verify the identity
7615-
of the client, place a root certificate on the server and a leaf and
7616-
optional intermediate certificates signed by the root certificate on
7617-
the client. Intermediate certificates (usually stored with the leaf
7618-
certificate) can also be used to link the leaf certificate to the
7619-
root certificate.
7615+
of the client, place a root certificate on the server and a leaf
7616+
certificate signed by the root certificate on the client. One or more
7617+
intermediate certificates (usually stored with the leaf certificate)
7618+
can also be used to link the leaf certificate to the root certificate.
76207619
</para>
76217620

76227621
<para>

doc/src/sgml/ref/create_trigger.sgml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -500,17 +500,17 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
500500
</para>
501501

502502
<para>
503-
Modifying a partitioned table or a table with inheritance children fires
504-
statement-level triggers directly attached to that table, but not
505-
statement-level triggers for its partitions or child tables. In contrast,
506-
row-level triggers are fired for all affected partitions or child tables.
507-
If a statement-level trigger has been defined with transition relations
508-
named by a <literal>REFERENCING</literal> clause, then before and after
509-
images of rows are visible from all affected partitions or child tables.
510-
In the case of inheritance children, the row images include only columns
511-
that are present in the table that the trigger is attached to. Currently,
512-
row-level triggers with transition relations cannot be defined on
513-
partitions or inheritance child tables.
503+
Modifying a partitioned table or a table with inheritance children fires
504+
statement-level triggers directly attached to that table, but not
505+
statement-level triggers for its partitions or child tables. In contrast,
506+
row-level triggers are fired for all affected partitions or child tables.
507+
If a statement-level trigger has been defined with transition relations
508+
named by a <literal>REFERENCING</literal> clause, then before and after
509+
images of rows are visible from all affected partitions or child tables.
510+
In the case of inheritance children, the row images include only columns
511+
that are present in the table that the trigger is attached to. Currently,
512+
row-level triggers with transition relations cannot be defined on
513+
partitions or inheritance child tables.
514514
</para>
515515

516516
<para>

doc/src/sgml/ref/pg_ctl-ref.sgml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,12 @@ doc/src/sgml/ref/pg_ctl-ref.sgml
405405
</para>
406406

407407
<para>
408-
When waiting for startup, <command>pg_ctl</command> repeatedly
409-
attempts to connect to the server.
410-
When waiting for shutdown, <command>pg_ctl</command> waits for
411-
the server to remove its <acronym>PID</acronym> file.
408+
When waiting, <command>pg_ctl</command> repeatedly checks the
409+
server's <acronym>PID</acronym> file, sleeping for a short amount
410+
of time between checks. Startup is considered complete when
411+
the <acronym>PID</acronym> file indicates that the server is ready to
412+
accept connections. Shutdown is considered complete when the server
413+
removes the <acronym>PID</acronym> file.
412414
<command>pg_ctl</command> returns an exit code based on the
413415
success of the startup or shutdown.
414416
</para>

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,9 @@ EOF
281281
<listitem>
282282
<para>
283283
List all available databases, then exit. Other non-connection
284-
options are ignored. This is similar to the meta-command
284+
options are ignored. If an explicit database name is not
285+
found the <literal>postgres</literal> database, not the user's,
286+
will be targeted for connection. This is similar to the meta-command
285287
<command>\list</command>.
286288
</para>
287289
</listitem>

src/backend/access/transam/parallel.c

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ static FixedParallelState *MyFixedParallelState;
107107
/* List of active parallel contexts. */
108108
static dlist_head pcxt_list = DLIST_STATIC_INIT(pcxt_list);
109109

110+
/* Backend-local copy of data from FixedParallelState. */
111+
static pid_t ParallelMasterPid;
112+
110113
/*
111114
* List of internal parallel worker entry points. We need this for
112115
* reasons explained in LookupParallelWorkerFunction(), below.
@@ -127,6 +130,7 @@ static const struct
127130
static void HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg);
128131
static void WaitForParallelWorkersToExit(ParallelContext *pcxt);
129132
static parallel_worker_main_type LookupParallelWorkerFunction(const char *libraryname, const char *funcname);
133+
static void ParallelWorkerShutdown(int code, Datum arg);
130134

131135

132136
/*
@@ -393,6 +397,11 @@ ReinitializeParallelDSM(ParallelContext *pcxt)
393397
WaitForParallelWorkersToFinish(pcxt);
394398
WaitForParallelWorkersToExit(pcxt);
395399
pcxt->nworkers_launched = 0;
400+
if (pcxt->any_message_received)
401+
{
402+
pfree(pcxt->any_message_received);
403+
pcxt->any_message_received = NULL;
404+
}
396405
}
397406

398407
/* Reset a few bits of fixed parallel state to a clean state. */
@@ -490,6 +499,14 @@ LaunchParallelWorkers(ParallelContext *pcxt)
490499
}
491500
}
492501

502+
/*
503+
* Now that nworkers_launched has taken its final value, we can initialize
504+
* any_message_received.
505+
*/
506+
if (pcxt->nworkers_launched > 0)
507+
pcxt->any_message_received =
508+
palloc0(sizeof(bool) * pcxt->nworkers_launched);
509+
493510
/* Restore previous memory context. */
494511
MemoryContextSwitchTo(oldcontext);
495512
}
@@ -511,6 +528,7 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt)
511528
for (;;)
512529
{
513530
bool anyone_alive = false;
531+
int nfinished = 0;
514532
int i;
515533

516534
/*
@@ -522,15 +540,78 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt)
522540

523541
for (i = 0; i < pcxt->nworkers_launched; ++i)
524542
{
525-
if (pcxt->worker[i].error_mqh != NULL)
543+
/*
544+
* If error_mqh is NULL, then the worker has already exited
545+
* cleanly. If we have received a message through error_mqh from
546+
* the worker, we know it started up cleanly, and therefore we're
547+
* certain to be notified when it exits.
548+
*/
549+
if (pcxt->worker[i].error_mqh == NULL)
550+
++nfinished;
551+
else if (pcxt->any_message_received[i])
526552
{
527553
anyone_alive = true;
528554
break;
529555
}
530556
}
531557

532558
if (!anyone_alive)
533-
break;
559+
{
560+
/* If all workers are known to have finished, we're done. */
561+
if (nfinished >= pcxt->nworkers_launched)
562+
{
563+
Assert(nfinished == pcxt->nworkers_launched);
564+
break;
565+
}
566+
567+
/*
568+
* We didn't detect any living workers, but not all workers are
569+
* known to have exited cleanly. Either not all workers have
570+
* launched yet, or maybe some of them failed to start or
571+
* terminated abnormally.
572+
*/
573+
for (i = 0; i < pcxt->nworkers_launched; ++i)
574+
{
575+
pid_t pid;
576+
shm_mq *mq;
577+
578+
/*
579+
* If the worker is BGWH_NOT_YET_STARTED or BGWH_STARTED, we
580+
* should just keep waiting. If it is BGWH_STOPPED, then
581+
* further investigation is needed.
582+
*/
583+
if (pcxt->worker[i].error_mqh == NULL ||
584+
pcxt->worker[i].bgwhandle == NULL ||
585+
GetBackgroundWorkerPid(pcxt->worker[i].bgwhandle,
586+
&pid) != BGWH_STOPPED)
587+
continue;
588+
589+
/*
590+
* Check whether the worker ended up stopped without ever
591+
* attaching to the error queue. If so, the postmaster was
592+
* unable to fork the worker or it exited without initializing
593+
* properly. We must throw an error, since the caller may
594+
* have been expecting the worker to do some work before
595+
* exiting.
596+
*/
597+
mq = shm_mq_get_queue(pcxt->worker[i].error_mqh);
598+
if (shm_mq_get_sender(mq) == NULL)
599+
ereport(ERROR,
600+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
601+
errmsg("parallel worker failed to initialize"),
602+
errhint("More details may be available in the server log.")));
603+
604+
/*
605+
* The worker is stopped, but is attached to the error queue.
606+
* Unless there's a bug somewhere, this will only happen when
607+
* the worker writes messages and terminates after the
608+
* CHECK_FOR_INTERRUPTS() near the top of this function and
609+
* before the call to GetBackgroundWorkerPid(). In that case,
610+
* or latch should have been set as well and the right things
611+
* will happen on the next pass through the loop.
612+
*/
613+
}
614+
}
534615

535616
WaitLatch(MyLatch, WL_LATCH_SET, -1,
536617
WAIT_EVENT_PARALLEL_FINISH);
@@ -787,6 +868,9 @@ HandleParallelMessage(ParallelContext *pcxt, int i, StringInfo msg)
787868
{
788869
char msgtype;
789870

871+
if (pcxt->any_message_received != NULL)
872+
pcxt->any_message_received[i] = true;
873+
790874
msgtype = pq_getmsgbyte(msg);
791875

792876
switch (msgtype)
@@ -981,11 +1065,16 @@ ParallelWorkerMain(Datum main_arg)
9811065
fps = shm_toc_lookup(toc, PARALLEL_KEY_FIXED, false);
9821066
MyFixedParallelState = fps;
9831067

1068+
/* Arrange to signal the leader if we exit. */
1069+
ParallelMasterPid = fps->parallel_master_pid;
1070+
ParallelMasterBackendId = fps->parallel_master_backend_id;
1071+
on_shmem_exit(ParallelWorkerShutdown, (Datum) 0);
1072+
9841073
/*
985-
* Now that we have a worker number, we can find and attach to the error
986-
* queue provided for us. That's good, because until we do that, any
987-
* errors that happen here will not be reported back to the process that
988-
* requested that this worker be launched.
1074+
* Now we can find and attach to the error queue provided for us. That's
1075+
* good, because until we do that, any errors that happen here will not be
1076+
* reported back to the process that requested that this worker be
1077+
* launched.
9891078
*/
9901079
error_queue_space = shm_toc_lookup(toc, PARALLEL_KEY_ERROR_QUEUE, false);
9911080
mq = (shm_mq *) (error_queue_space +
@@ -1098,9 +1187,6 @@ ParallelWorkerMain(Datum main_arg)
10981187
SetTempNamespaceState(fps->temp_namespace_id,
10991188
fps->temp_toast_namespace_id);
11001189

1101-
/* Set ParallelMasterBackendId so we know how to address temp relations. */
1102-
ParallelMasterBackendId = fps->parallel_master_backend_id;
1103-
11041190
/*
11051191
* We've initialized all of our state now; nothing should change
11061192
* hereafter.
@@ -1142,6 +1228,20 @@ ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
11421228
SpinLockRelease(&fps->mutex);
11431229
}
11441230

1231+
/*
1232+
* Make sure the leader tries to read from our error queue one more time.
1233+
* This guards against the case where we exit uncleanly without sending an
1234+
* ErrorResponse to the leader, for example because some code calls proc_exit
1235+
* directly.
1236+
*/
1237+
static void
1238+
ParallelWorkerShutdown(int code, Datum arg)
1239+
{
1240+
SendProcSignal(ParallelMasterPid,
1241+
PROCSIG_PARALLEL_MESSAGE,
1242+
ParallelMasterBackendId);
1243+
}
1244+
11451245
/*
11461246
* Look up (and possibly load) a parallel worker entry point function.
11471247
*

src/backend/executor/nodeIndexonlyscan.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,39 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node)
421421

422422
/* ----------------------------------------------------------------
423423
* ExecIndexOnlyMarkPos
424+
*
425+
* Note: we assume that no caller attempts to set a mark before having read
426+
* at least one tuple. Otherwise, ioss_ScanDesc might still be NULL.
424427
* ----------------------------------------------------------------
425428
*/
426429
void
427430
ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
428431
{
432+
EState *estate = node->ss.ps.state;
433+
434+
if (estate->es_epqTuple != NULL)
435+
{
436+
/*
437+
* We are inside an EvalPlanQual recheck. If a test tuple exists for
438+
* this relation, then we shouldn't access the index at all. We would
439+
* instead need to save, and later restore, the state of the
440+
* es_epqScanDone flag, so that re-fetching the test tuple is
441+
* possible. However, given the assumption that no caller sets a mark
442+
* at the start of the scan, we can only get here with es_epqScanDone
443+
* already set, and so no state need be saved.
444+
*/
445+
Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid;
446+
447+
Assert(scanrelid > 0);
448+
if (estate->es_epqTupleSet[scanrelid - 1])
449+
{
450+
/* Verify the claim above */
451+
if (!estate->es_epqScanDone[scanrelid - 1])
452+
elog(ERROR, "unexpected ExecIndexOnlyMarkPos call in EPQ recheck");
453+
return;
454+
}
455+
}
456+
429457
index_markpos(node->ioss_ScanDesc);
430458
}
431459

@@ -436,6 +464,23 @@ ExecIndexOnlyMarkPos(IndexOnlyScanState *node)
436464
void
437465
ExecIndexOnlyRestrPos(IndexOnlyScanState *node)
438466
{
467+
EState *estate = node->ss.ps.state;
468+
469+
if (estate->es_epqTuple != NULL)
470+
{
471+
/* See comments in ExecIndexOnlyMarkPos */
472+
Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid;
473+
474+
Assert(scanrelid > 0);
475+
if (estate->es_epqTupleSet[scanrelid - 1])
476+
{
477+
/* Verify the claim above */
478+
if (!estate->es_epqScanDone[scanrelid - 1])
479+
elog(ERROR, "unexpected ExecIndexOnlyRestrPos call in EPQ recheck");
480+
return;
481+
}
482+
}
483+
439484
index_restrpos(node->ioss_ScanDesc);
440485
}
441486

0 commit comments

Comments
 (0)