Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gbYXH-0003Eh-4E for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Dec 2018 22:17:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gbYWG-0002xc-0F for pgsql-hackers@arkaria.postgresql.org; Mon, 24 Dec 2018 22:16:16 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gbYWF-0002vK-Cn for pgsql-hackers@lists.postgresql.org; Mon, 24 Dec 2018 22:16:15 +0000 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gbYW7-0001Ao-P5 for pgsql-hackers@postgresql.org; Mon, 24 Dec 2018 22:16:13 +0000 Received: by mail-pf1-x441.google.com with SMTP id 64so6176099pfr.9 for ; Mon, 24 Dec 2018 14:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=pCGsROQtrKDK/dQR8Mn6ImFWelZCGQYzmV25GhLHGdE=; b=QiVB2N5KJlq8GSAyAgkbTYUk5IEiJ6I33zAysQHJQ6rrSJnLQA78FfP0sENxHWEoHC oYqm5RP1k4Kh3EAGEqMjN6oWkgg3VI0qELJLoMeTzbYZwyEX53QD+1/XiUbkfnwZ/vpk 8PWj2kv5zZWJXURUzjQ7yo3Magu50lJLx+LXY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=pCGsROQtrKDK/dQR8Mn6ImFWelZCGQYzmV25GhLHGdE=; b=gdTNYu4EVGQ7ky4vs8AvT9jx/DRMRroy1A8w4v1cN+hA87oMZEYDYyCem+Bzt2FM+t khfqXcKfjQQUxBkbeCn5kMLM5FFz+kVvUmqq6WQ3AdrESj16MZhAT7gqOWxYAoutAoBh Y1LAq1EGNIHUIe8vQsSDvqyzJzGGT/vUcWkRp7DpkeFZMRTiuxrgAGaWlfKENbphdA97 2MkW1yXqzQhIVzCpwfZNvZobgdvaVHOEzSP4fQqSqs4oQbfw8MV8DJmTk4IshPF0boBG JWhZ9Rt8IWJMFsQDW+M+xI5b4VgcnE9dtAe78Z+YBN1TVCxHq0vRYuVpleBgdjM/KK1K DTXw== X-Gm-Message-State: AJcUukf67A8vY9qb694SE4V0+QfBVzVKh+K06hDr5hK2Ip/Dsk27lc08 7lOI+7p7QRR3N05r5WV4s9b0l+HHv0Y= X-Google-Smtp-Source: ALg8bN6GywaKPvAel4SuSybMgTy5Be9xhIvTxMptzsXFNppBFSM1eteN1MG1m+ApBeCVYV+oxI95vg== X-Received: by 2002:a63:bd1a:: with SMTP id a26mr13562798pgf.121.1545689765320; Mon, 24 Dec 2018 14:16:05 -0800 (PST) Received: from rfd.leadboat.com (c-73-158-248-138.hsd1.ca.comcast.net. [73.158.248.138]) by smtp.gmail.com with ESMTPSA id 4sm58023930pfq.10.2018.12.24.14.16.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Dec 2018 14:16:03 -0800 (PST) Date: Mon, 24 Dec 2018 14:16:01 -0800 From: Noah Misch To: pgsql-hackers@postgresql.org Subject: Re: Race to build pg_isolation_regress in "make -j check-world" Message-ID: <20181224221601.GA3227827@rfd.leadboat.com> References: <20171106080752.GA1298146@rfd.leadboat.com> <20171217040605.GA2421254@rfd.leadboat.com> <20180102013956.GA898314@rfd.leadboat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="wac7ysb48OaltWcw" Content-Disposition: inline In-Reply-To: <20180102013956.GA898314@rfd.leadboat.com> User-Agent: Mutt/1.5.24 (2015-08-30) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Jan 01, 2018 at 05:39:56PM -0800, Noah Misch wrote: > On Sat, Dec 16, 2017 at 08:06:05PM -0800, Noah Misch wrote: > > On Mon, Nov 06, 2017 at 12:07:52AM -0800, Noah Misch wrote: > > > I now see similar trouble from multiple > > "make" processes running "make -C contrib/test_decoding install" concurrently. > > This is a risk for any directory named in an EXTRA_INSTALL variable of more > > than one makefile. Under the right circumstances, this would affect > > contrib/hstore and others in addition to contrib/test_decoding. That brings > > me back to the locking idea: > > > > > The problem of multiple "make" processes in a directory (especially src/port) > > > shows up elsewhere. In a cleaned tree, "make -j -C src/bin" or "make -j > > > installcheck-world" will do it. For more-prominent use cases, src/Makefile > > > prevents this with ".NOTPARALLEL:" and building first the directories that are > > > frequent submake targets. Perhaps we could fix the general problem with > > > directory locking; targets that call "$(MAKE) -C FOO" would first sleep until > > > FOO's lock is available. That could be tricky to make robust. > Performance has been the principal snare. I value "make -j" being fast when > there's little to rebuild, but that shell script approach slowed an empty > build by 340% (GNU/Linux w/ SSD) to 2300% (Cygwin). In a build having nothing > to do, merely adding a no-op wrapper around "make -C" (does nothing but > execvp() the real GNU make) slowed the build by over 10%[1]. To get what I > considered decent performance took several design changes: > 3. Lock only directories known to be entered more than once per top-level > target. Preliminarily, this reduced the 147 lock acquisitions to 25. > > I regret that (3) entails ongoing maintenance of a whitelist of such > directories; adding a "make -C" call can expand the list. However, I can > automate verification of that whitelist. As I developed this more, I found it dissatisfying. To verify the whitelist, one empties the whitelist, rebuilds each makefile target, and reassembles the whitelist from the list of directories visited more than once within a target. That's too expensive to run all the time (e.g. with every "make check"). I could make a buildfarm animal turn red when the whitelist is out of date, but I wouldn't enjoy discovering or fixing whitelist drift that way. Hence, I'm back to preferring fixes targeting the known problems: - Fix conflicting writes in src/test/regress: https://postgr.es/m/flat/20181224034411.GA3224776%40rfd.leadboat.com - Fix conflicting EXTRA_INSTALL, detailed above. In the MAKELEVEL-0 part of the temp-install Makefile target, serially process all applicable EXTRA_INSTALL. See attached patch. On my usual development system, this adds <2s to "make check-world" and <0.1s to "make check" or "make -C contrib/earthdistance check". To corroborate the sufficiency of those two patches, I ran 110 iterations of "make -j40" and "make -j40 check-world" without encountering a failure attributable to parallel make. I also ran those targets at excess parallelism (-j120) and audited the list of commands appearing more than once: make clean && make -j120 2>&1 | sort | uniq -c | sort -rn make -j120 check-world 2>&1 | sort | uniq -c | sort -rn Unlike the locking method, this doesn't fix clean-tree "make -j -C src/bin" or clean-tree "make -j installcheck-world". Thanks, nm --wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="extra_install-serial-v1.patch" --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -63,10 +63,12 @@ distclean maintainer-clean: @rm -rf autom4te.cache/ rm -f config.cache config.log config.status GNUmakefile +check check-tests installcheck installcheck-parallel installcheck-tests: CHECKPREP_TOP=src/test/regress check check-tests installcheck installcheck-parallel installcheck-tests: submake-generated-headers $(MAKE) -C src/test/regress $@ $(call recurse,check-world,src/test src/pl src/interfaces/ecpg contrib src/bin,check) +$(call recurse,checkprep, src/test src/pl src/interfaces/ecpg contrib src/bin) $(call recurse,installcheck-world,src/test src/pl src/interfaces/ecpg contrib src/bin,installcheck) --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -19,7 +19,7 @@ # # Meta configuration -standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check installcheck init-po update-po +standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check checkprep installcheck init-po update-po # these targets should recurse even into subdirectories not being built: standard_always_targets = distprep clean distclean maintainer-clean @@ -390,11 +390,17 @@ ifeq ($(MAKELEVEL),0) rm -rf '$(abs_top_builddir)'/tmp_install $(MKDIR_P) '$(abs_top_builddir)'/tmp_install/log $(MAKE) -C '$(top_builddir)' DESTDIR='$(abs_top_builddir)'/tmp_install install >'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 + $(MAKE) -j1 $(if $(CHECKPREP_TOP),-C $(CHECKPREP_TOP),) checkprep >>'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 endif - $(if $(EXTRA_INSTALL),for extra in $(EXTRA_INSTALL); do $(MAKE) -C '$(top_builddir)'/$$extra DESTDIR='$(abs_top_builddir)'/tmp_install install >>'$(abs_top_builddir)'/tmp_install/log/install.log || exit; done) endif endif +# Tasks to run serially at the end of temp-install. Some EXTRA_INSTALL +# entries appear more than once in the tree, and parallel installs of the same +# file can fail with EEXIST. +checkprep: + $(if $(EXTRA_INSTALL),for extra in $(EXTRA_INSTALL); do $(MAKE) -C '$(top_builddir)'/$$extra DESTDIR='$(abs_top_builddir)'/tmp_install install || exit; done) + PROVE = @PROVE@ # There are common routines in src/test/perl, and some test suites have # extra perl modules in their own directory. --- a/src/makefiles/pgxs.mk +++ b/src/makefiles/pgxs.mk @@ -435,7 +435,7 @@ endif endif # PGXS ifndef NO_TEMP_INSTALL -temp-install: EXTRA_INSTALL+=$(subdir) +checkprep: EXTRA_INSTALL+=$(subdir) endif --wac7ysb48OaltWcw--