未验证 提交 00da6bbf 编写于 作者: N Ning Yu 提交者: GitHub

Test termination during gang creation

There was a double free issue which was fixed in 772bca3f, add test
case for it.

    commit 772bca3f
    Author: Pengzhou Tang <ptang@pivotal.io>
    Date:   Tue Mar 20 22:06:50 2018 -0400

        Fix SIGSEGV issue when freeing gangs

        Previously, to avoid the leak of the gang if someone terminates
        the query in the middle of gang creation, we added a global pointer
        named CurrentGangCreating so the partially created gang can also be
        destroyed at the end of the transaction. However, the memory context
        named GangContext where CurrentGangCreating was created may be reset
        before CurrentGangCreating is actually destroyed and a SIGSEGV may
        occur. So this commit makes sure that CurrentGangCreating is destroyed
        ahead of other created gangs and the reset of GangContext.
Co-Authored-by: NJialun Du <jdu@pivotal.io>
Co-Authored-by: NNing Yu <nyu@pivotal.io>
上级 048c7acb
......@@ -1512,6 +1512,9 @@ freeGangsForPortal(char *portal_name)
{
GangType type = CurrentGangCreating->type;
Assert(type >= GANGTYPE_UNALLOCATED &&
type <= GANGTYPE_PRIMARY_WRITER);
DisconnectAndDestroyGang(CurrentGangCreating);
CurrentGangCreating = NULL;
......
......@@ -234,6 +234,8 @@ create_gang_retry:
if (nfds == 0)
break;
SIMPLE_FAULT_INJECTOR(CreateGangInProgress);
CHECK_FOR_INTERRUPTS();
/* Wait until something happens */
......
......@@ -247,6 +247,8 @@ FI_IDENT(AutoVacWorkerBeforeDoAutovacuum, "auto_vac_worker_before_do_autovacuum"
FI_IDENT(GetDnsCachedAddress, "get_dns_cached_address")
/* inject fault before notify fts probe */
FI_IDENT(BeforeFtsNotify, "before_fts_notify")
/* inject fault during gang creation, before check for interrupts */
FI_IDENT(CreateGangInProgress, "create_gang_in_progress")
#endif
/*
......
......@@ -24,3 +24,50 @@ count
-----
10
(1 row)
--
-- SIGSEGV issue when freeing gangs
--
CREATE EXTENSION IF NOT EXISTS gp_inject_fault;
CREATE
DROP TABLE IF EXISTS foo;
DROP
CREATE TABLE foo (c1 int, c2 int) DISTRIBUTED BY (c1);
CREATE
10: BEGIN;
BEGIN
SELECT gp_inject_fault('create_gang_in_progress', 'reset', 1);
gp_inject_fault
---------------
t
(1 row)
SELECT gp_inject_fault('create_gang_in_progress', 'suspend', 1);
gp_inject_fault
---------------
t
(1 row)
10&: SELECT * FROM foo a JOIN foo b USING (c2); <waiting ...>
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE query = 'SELECT * FROM foo a JOIN foo b USING (c2);';
pg_terminate_backend
--------------------
t
(1 row)
SELECT gp_inject_fault('create_gang_in_progress', 'resume', 1);
gp_inject_fault
---------------
t
(1 row)
10<: <... completed>
FATAL: terminating connection due to administrator command
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
10q
......@@ -12,3 +12,27 @@ FROM pg_stat_activity WHERE query like 'create temp table t as select%' ORDER BY
-- query backend to ensure no PANIC on postmaster
select count(*) from foo;
--
-- SIGSEGV issue when freeing gangs
--
CREATE EXTENSION IF NOT EXISTS gp_inject_fault;
DROP TABLE IF EXISTS foo;
CREATE TABLE foo (c1 int, c2 int) DISTRIBUTED BY (c1);
10: BEGIN;
SELECT gp_inject_fault('create_gang_in_progress', 'reset', 1);
SELECT gp_inject_fault('create_gang_in_progress', 'suspend', 1);
10&: SELECT * FROM foo a JOIN foo b USING (c2);
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE query = 'SELECT * FROM foo a JOIN foo b USING (c2);';
SELECT gp_inject_fault('create_gang_in_progress', 'resume', 1);
10<:
10q
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册